“Baby Mental Life: Study 2” was conducted on MTurk on 2018-08-04.

Our planned sample was 300 participants, and we anticipated that roughly 80% of recruited participants would pass all of our attention checks, so we initially recruited 378 participants (on the idea that ~80% of 378 ~ 300 participants; note that for administrative purposes we need to recuit participants in batches that were divisible by 9). After filtering out participants who failed at least one of our attention checks, we ended up retaining fewer than 300 participants, so we recruited an additional 16 participants for a total of 394 people recruited. At each stage, we recruited women and men through separate studies, in hopes of acquiring a roughly equal split between genders.

In the end, we ended up with a sample of 304 participants who passed our attention checks, 237 of whom came from unique GPS coordinates.

For this first pass, these data exclude participants where there is another participant with an identical set of GPS coordinates as recorded by Qualtrics.

Each participant assessed children’s mental capacities at 13 target ages between the ages of 0 and 5 years. For each target, they rated 20 mental capacities on a scale from 0 (not at all capable) to 100 (completely capable).

For more details about the study, see our preregistration here.

Here we run some exploratory analyses on these data.

# load required libraries
library(tidyverse)
library(langcog) # source: https://github.com/langcog/langcog-package
library(psych)
library(lme4)
# set theme for ggplots
theme_set(theme_bw())
# run source code (extra home-made functions)
source("./scripts/max_factors_efa.R")
source("./scripts/plot_fun.R")
source("./scripts/reten_fun.R")
source("./scripts/table_fun.R")
source("./scripts/data_prep.R")
NAs introduced by coercionattributes are not identical across measure variables;
they will be droppedJoining, by = "question_qualtrics"

Treating factors as categories

Preliminaries

First, I’ll do the factor analysis, and get a list of the top 5 items by factor:

# load in S1 efa in case we need it
efa_S1 <- readRDS("../study 1/s1_efa.rds")
demo_S1 <- read.csv("../study 1/s1_demo.csv")
# conduct S2 efa
efa_S2 <- fa(d_all, nfactors = 4, rotate = "oblimin", fm = "minres",
             scores = "tenBerge", impute = "median")
Loading required namespace: GPArotation
table_fun(efa_S2, num_items = 5, pos_abs = "abs")
capacity loading
Factor 1
feeling_distressed 0.82
feeling_overwhelmed 0.82
feeling_frustrated 0.78
feeling_helpless 0.76
feeling_lonely 0.60
Factor 2
having_self_control 0.96
controlling_their_emotions 0.93
telling_right_from_wrong 0.93
planning 0.89
reasoning_about_things 0.89
Factor 3
getting_hungry 0.83
feeling_pain 0.79
feeling_tired 0.67
hearing_sounds 0.58
feeling_physically_uncomfortable 0.49
Factor 4
feeling_happy 0.82
finding_something_funny 0.81
feeling_excited 0.79
loving_somebody 0.64
learning_from_other_people 0.51

Now I’ll use this to define categories of mental capacities:

# get items by factor
factors_S2 <- efa_S2$loadings[] %>%
  data.frame() %>%
  rownames_to_column("capacity") %>%
  gather(factor, loading, -capacity) %>%
  group_by(capacity) %>%
  top_n(1, loading) %>%
  ungroup() %>%
  select(-loading) %>%
  mutate(factor_names = recode_factor(factor,
                                      "MR1" = "Negative emotions",
                                      "MR2" = "Cognition & control",
                                      "MR3" = "Bodily sensations",
                                      "MR4" = "Positive/social emotions"),
         factor = factor(factor))
# make new dataframe
d_cat <- d_all %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(capacity, response, -c(subid, starts_with("target"))) %>%
  left_join(factors_S2) %>%
  left_join(d_demo %>%
              select(ResponseId, Parent) %>%
              rename(subid = ResponseId, parent = Parent) %>%
              mutate(subid = as.character(subid)))
Joining, by = "capacity"
Joining, by = "subid"

Check reliability (Cronbach’s alpha):

d_cat %>% 
  filter(factor == "MR1") %>% 
  mutate(subid_target = paste(subid, target, sep = "_")) %>%
  select(subid_target, capacity, response) %>%
  spread(capacity, response) %>%
  column_to_rownames("subid_target") %>%
  cor() %>%
  alpha(title = "MR1: Negative emotions")

Reliability analysis  MR1: Negative emotions  
Call: alpha(x = ., title = "MR1: Negative emotions")

 

 Reliability if an item is dropped:

 Item statistics 
d_cat %>% 
  filter(factor == "MR2") %>% 
  mutate(subid_target = paste(subid, target, sep = "_")) %>%
  select(subid_target, capacity, response) %>%
  spread(capacity, response) %>%
  column_to_rownames("subid_target") %>%
  cor() %>%
  alpha(title = "MR2: Cognition & control")

Reliability analysis  MR2: Cognition & control  
Call: alpha(x = ., title = "MR2: Cognition & control")

 

 Reliability if an item is dropped:

 Item statistics 
d_cat %>% 
  filter(factor == "MR3") %>% 
  mutate(subid_target = paste(subid, target, sep = "_")) %>%
  select(subid_target, capacity, response) %>%
  spread(capacity, response) %>%
  column_to_rownames("subid_target") %>%
  cor() %>%
  alpha(title = "MR3: Bodily sensations")

Reliability analysis  MR3: Bodily sensations  
Call: alpha(x = ., title = "MR3: Bodily sensations")

 

 Reliability if an item is dropped:

 Item statistics 
d_cat %>% 
  filter(factor == "MR4") %>% 
  mutate(subid_target = paste(subid, target, sep = "_")) %>%
  select(subid_target, capacity, response) %>%
  spread(capacity, response) %>%
  column_to_rownames("subid_target") %>%
  cor() %>%
  alpha(title = "MR4: Social abilities & positive emotions")

Reliability analysis  MR4: Social abilities & positive emotions  
Call: alpha(x = ., title = "MR4: Social abilities & positive emotions")

 

 Reliability if an item is dropped:

 Item statistics 

And get an average “score” for each of these factors for each participant:

d_cat_scored <- d_cat %>%
  group_by(subid, parent, 
           target, target_num, target_ord, 
           factor, factor_names) %>%
  summarise(score = mean(response, na.rm = T)) %>%
  ungroup()

Plots

# bootstrapped means and 95% CIs
d_cat_scored_boot <- d_cat_scored %>%
  group_by(target, target_num, target_ord, factor, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup()
ggplot(d_cat_scored,
       aes(x = target_num, y = score, color = factor_names)) +
  facet_grid(~ factor_names) +
  geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_scored_boot, color = "black",
            aes(y = mean, group = factor_names)) +
  geom_pointrange(data = d_cat_scored_boot, color = "black", fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set2", guide = "none") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, untransformed",
       x = "target age (months)")

ggplot(d_cat_scored,
       aes(x = target_num, y = score, color = factor_names)) +
  facet_grid(~ factor_names) +
  geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_scored_boot, color = "black",
            aes(y = mean, group = factor_names)) +
  geom_pointrange(data = d_cat_scored_boot, color = "black", fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set2", guide = "none") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
  scale_x_continuous(breaks = seq(0, 60, 12), trans = "sqrt") +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, square-root-transformed",
       x = "age after square-root transformation (months)")

ggplot(d_cat_scored,
       aes(x = target_ord, y = score, color = factor_names)) +
  facet_grid(~ factor_names) +
  geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_scored_boot, color = "black",
            aes(y = mean, group = factor_names)) +
  geom_pointrange(data = d_cat_scored_boot, color = "black", fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set2", guide = "none") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Age as an ordinal variable",
       x = "age (ordinal)")

Regressions

# contrasts(d_cat_scored$target_ord) <- contr.poly(13)
# contrasts(d_cat_scored$factor) <- contr.sum(4)
contrasts(d_cat$target_ord) <- contr.poly(13)
contrasts(d_cat$factor) <- contr.sum(4)
r1 <- lmer(response ~ factor * poly(target_num, 3) +
             (1 + factor + target_num | subid),
           d_cat %>%
             mutate(target_num = scale(target_num, center = F)))
summary(r1)
Linear mixed model fit by REML ['lmerMod']
Formula: response ~ factor * poly(target_num, 3) + (1 + factor + target_num |  
    subid)
   Data: d_cat %>% mutate(target_num = scale(target_num, center = F))

REML criterion at convergence: 536724.6

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-5.5360 -0.4298  0.0225  0.5167  5.5499 

Random effects:
 Groups   Name        Variance Std.Dev. Corr                   
 subid    (Intercept) 200.49   14.159                          
          factor1     156.13   12.495    0.65                  
          factor2     145.83   12.076   -0.44 -0.59            
          factor3      69.75    8.352   -0.55 -0.34 -0.24      
          target_num   51.83    7.199   -0.64 -0.42  0.50  0.31
 Residual             334.01   18.276                          
Number of obs: 61620, groups:  subid, 237

Fixed effects:
                               Estimate Std. Error t value
(Intercept)                     68.3739     0.7634  89.569
factor1                          6.9512     0.8216   8.461
factor2                        -38.7255     0.7947 -48.728
factor3                         25.1428     0.5573  45.116
poly(target_num, 3)1          3241.2664    88.4095  36.662
poly(target_num, 3)2         -1237.5812    18.2759 -67.717
poly(target_num, 3)3           532.0777    18.2759  29.114
factor1:poly(target_num, 3)1  -544.0136    31.6548 -17.186
factor2:poly(target_num, 3)1  2670.8981    31.6548  84.376
factor3:poly(target_num, 3)1 -2550.8843    31.6548 -80.584
factor1:poly(target_num, 3)2    32.5828    31.6548   1.029
factor2:poly(target_num, 3)2    38.2604    31.6548   1.209
factor3:poly(target_num, 3)2   881.6516    31.6548  27.852
factor1:poly(target_num, 3)3    48.0128    31.6548   1.517
factor2:poly(target_num, 3)3  -391.9779    31.6548 -12.383
factor3:poly(target_num, 3)3  -354.1489    31.6548 -11.188

Correlation matrix not shown by default, as p = 16 > 12.
Use print(x, correlation=TRUE)  or
     vcov(x)     if you need it

This is weirdly hard to model… lots of alternative models didn’t converge. Also, those extremely high t-values make me a little suspicious, as do the identical standard errors for the last 9 terms. So, let’s take this with a bit of a grain of salt for now.

Parents vs. non-parents

Study 2

Preliminaries

d_parent <- d_all %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(capacity, response, -c(subid, starts_with("target"))) %>%
  left_join(d_demo %>%
              select(ResponseId, Parent) %>%
              rename(subid = ResponseId, parent = Parent) %>%
              mutate(subid = as.character(subid)))
Joining, by = "subid"
parent_counts <- d_demo %>% 
  distinct(ResponseId, Parent) %>% 
  rename(subid = ResponseId, parent = Parent) %>%
  count(parent) %>% 
  mutate(proportion = n/sum(n))
knitr::kable(parent_counts, digits = 3)
parent n proportion
No 146 0.616
Yes 88 0.371
NA 3 0.013
d_demo %>%
  count(Parent, ChildrenOldestAge_collapse)

Given these numbers, I think our best bet it just to look at parents vs. non-parents, and not try to separate out parents of young children (too few!).

scores_S2 <- efa_S2$scores %>%
  data.frame() %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(factor, score, -c(subid, starts_with("target"))) %>%
  left_join(d_parent %>% distinct(subid, parent)) %>%
  left_join(d_cat %>% distinct(factor, factor_names)) %>%
  mutate(factor = factor(factor))
Joining, by = "subid"
Joining, by = "factor"
Column `factor` joining character vector and factor, coercing into character vector

Plots

Factor scores

# bootstrapped means and 95% CIs
d_parent_boot <- scores_S2 %>%
  filter(!is.na(parent)) %>%
  group_by(parent, target, target_num, target_ord, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup() %>%
  data.frame()
scores_S2 %>%
  filter(!is.na(parent)) %>%
  ggplot(aes(x = target_num, y = score, color = parent)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_parent_boot, aes(y = mean, group = parent)) +
  geom_pointrange(data = d_parent_boot, fatten = 1.5, # note: too close to dodge
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = parent), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by parent status",
       subtitle = "Exact age, untransformed",
       color = "parent status: ",
       x = "target age (months)", y = "score (NOTE: scales differ)")

scores_S2 %>%
  filter(!is.na(parent)) %>%
  ggplot(aes(x = target_num, y = score, color = parent)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_parent_boot, aes(y = mean, group = parent),
            position = position_dodge(width = 0.3)) +
  geom_pointrange(data = d_parent_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper),
                  position = position_dodge(width = 0.3)) +
  # geom_smooth(aes(group = parent), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12), trans = "sqrt") +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by parent status",
       subtitle = "Exact age, square-root transformed",
       color = "parent status: ",
       x = "age after square-root transformation (months)", 
       y = "score (NOTE: scales differ)")

scores_S2 %>%
  filter(!is.na(parent)) %>%
  ggplot(aes(x = target_ord, y = score, color = parent)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_parent_boot, aes(y = mean, group = parent),
            position = position_dodge(width = 0.5)) +
  geom_pointrange(data = d_parent_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper),
                  position = position_dodge(width = 0.5)) +
  # geom_smooth(aes(group = parent), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by parent status",
       subtitle = "Age as ordinal variable",
       color = "parent status: ",
       x = "age (ordinal)", 
       y = "score (NOTE: scales differ)")

Category ‘summary scores’

# bootstrapped means and 95% CIs
d_cat_parent_scored_boot <- d_cat_scored %>%
  filter(!is.na(parent)) %>%
  group_by(parent, target, target_num, target_ord, factor, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup()
ggplot(d_cat_parent_scored_boot,
       aes(x = target_num, y = score, color = parent)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_parent_scored_boot, 
            aes(y = mean, group = parent)) +
  geom_pointrange(data = d_cat_parent_scored_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, untransformed",
       x = "target age (months)",
       y = "score (NOTE: scales differ)")

ggplot(d_cat_parent_scored_boot,
       aes(x = target_num, y = score, color = parent)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_parent_scored_boot, 
            aes(y = mean, group = parent)) +
  geom_pointrange(data = d_cat_parent_scored_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12), trans = "sqrt") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, square-root transformation",
       x = "age after square-root transformation (months)",
       y = "score (NOTE: scales differ)")

ggplot(d_cat_parent_scored_boot,
       aes(x = target_ord, y = score, color = parent)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_parent_scored_boot, 
            aes(y = mean, group = parent)) +
  geom_pointrange(data = d_cat_parent_scored_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Age as an ordinal variable",
       x = "age (ordinal)",
       y = "score (NOTE: scales differ)")

All of these visualizations suggest that, relative to non-parents (n = NA), parents (n = NA) tended to perceive greater abilities, in all domains except for bodily sensations. For both negative emotions and positive/social emotions, this difference is greatest in the mid-range of the target ages (12-24 months); for cognition & control, it’s greater at the older end of the target ages (e.g., 3-5 years). It doesn’t look like a huge effect, but it’s intruiging.

Regressions

There are many ways that we could choose to model this - I’ll try out the factor scores first, adapting our primary regression models (not in this notebook).

contrasts(scores_S2$parent) <- contr.treatment(2, base = 1) # baseline: NON-parents
contrasts(scores_S2$factor) <- contr.sum(4)
r2 <- lmer(score ~ target_num * factor * parent
           + (target_num + factor | subid),
           scores_S2 %>%
             mutate(target_num = target_num/12))
summary(r2)
Linear mixed model fit by REML ['lmerMod']
Formula: score ~ target_num * factor * parent + (target_num + factor |  
    subid)
   Data: scores_S2 %>% mutate(target_num = target_num/12)

REML criterion at convergence: 22480.5

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-9.3553 -0.4388  0.0524  0.5114  5.2974 

Random effects:
 Groups   Name        Variance Std.Dev. Corr                   
 subid    (Intercept) 0.3491   0.5908                          
          target_num  0.0165   0.1284   -0.73                  
          factor1     0.1947   0.4413    0.49 -0.40            
          factor2     0.2303   0.4799   -0.66  0.56 -0.40      
          factor3     0.2605   0.5104    0.24  0.00 -0.22 -0.61
 Residual             0.2919   0.5403                          
Number of obs: 12168, groups:  subid, 234

Fixed effects:
                            Estimate Std. Error t value
(Intercept)                -0.424399   0.049602  -8.556
target_num                  0.279097   0.011334  24.624
factor1                     0.078297   0.039260   1.994
factor2                    -0.273518   0.042253  -6.473
factor3                     0.253010   0.044634   5.669
parent2                     0.070601   0.080884   0.873
target_num:factor1         -0.058596   0.006811  -8.603
target_num:factor2          0.190717   0.006811  28.001
target_num:factor3         -0.170985   0.006811 -25.104
target_num:parent2          0.003333   0.018482   0.180
factor1:parent2             0.005619   0.064020   0.088
factor2:parent2            -0.051089   0.068900  -0.741
factor3:parent2             0.031692   0.072783   0.435
target_num:factor1:parent2 -0.002939   0.011107  -0.265
target_num:factor2:parent2  0.053753   0.011107   4.840
target_num:factor3:parent2 -0.046204   0.011107  -4.160

Correlation matrix not shown by default, as p = 16 > 12.
Use print(x, correlation=TRUE)  or
     vcov(x)     if you need it

The last three coefficients here are where the action is: According to this model, the difference between parents and non-parents in perceived developmental trajectories (target_num:parent2, which is not significant collapsing across factors) is exaggerated in the domain of cognition and control (target_num:factor2:parent2) and diminished in the domain of bodily sensations (target_num:factor3:parent2).

Let’s try adding polynomial effects:

r3 <- lmer(score ~ poly(target_num, 3) * factor * parent
           + (poly(target_num, 1) + factor | subid),
           scores_S2 %>%
             mutate(target_num = target_num/12))
summary(r3)
Linear mixed model fit by REML ['lmerMod']
Formula: score ~ poly(target_num, 3) * factor * parent + (poly(target_num,  
    1) + factor | subid)
   Data: scores_S2 %>% mutate(target_num = target_num/12)

REML criterion at convergence: 19808.5

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-10.3042  -0.4652   0.0017   0.5305   5.8317 

Random effects:
 Groups   Name                Variance Std.Dev. Corr                   
 subid    (Intercept)           0.2278  0.4773                         
          poly(target_num, 1) 519.8012 22.7991  -0.51                  
          factor1               0.1982  0.4452   0.45 -0.39            
          factor2               0.2338  0.4835  -0.60  0.54 -0.40      
          factor3               0.2640  0.5138   0.30  0.00 -0.22 -0.61
 Residual                       0.2316  0.4812                         
Number of obs: 12168, groups:  subid, 234

Fixed effects:
                                       Estimate Std. Error t value
(Intercept)                           -0.030561   0.039884  -0.766
poly(target_num, 3)1                  48.855288   1.983984  24.625
poly(target_num, 3)2                 -19.550418   0.613116 -31.887
poly(target_num, 3)3                   8.448995   0.613116  13.780
factor1                               -0.004388   0.038065  -0.115
factor2                               -0.004395   0.041145  -0.107
factor3                                0.011731   0.043587   0.269
parent2                                0.075304   0.065038   1.158
poly(target_num, 3)1:factor1         -10.257028   1.061949  -9.659
poly(target_num, 3)2:factor1           3.413024   1.061949   3.214
poly(target_num, 3)3:factor1          -1.785482   1.061949  -1.681
poly(target_num, 3)1:factor2          33.384462   1.061949  31.437
poly(target_num, 3)2:factor2           3.384910   1.061949   3.187
poly(target_num, 3)3:factor2          -6.433547   1.061949  -6.058
poly(target_num, 3)1:factor3         -29.930494   1.061949 -28.184
poly(target_num, 3)2:factor3           8.594647   1.061949   8.093
poly(target_num, 3)3:factor3          -3.251241   1.061949  -3.062
poly(target_num, 3)1:parent2           0.583455   3.235228   0.180
poly(target_num, 3)2:parent2          -2.031708   0.999792  -2.032
poly(target_num, 3)3:parent2           1.883539   0.999792   1.884
factor1:parent2                        0.001472   0.062072   0.024
factor2:parent2                        0.024763   0.067094   0.369
factor3:parent2                       -0.033507   0.071076  -0.471
poly(target_num, 3)1:factor1:parent2  -0.514473   1.731690  -0.297
poly(target_num, 3)2:factor1:parent2  -0.041808   1.731690  -0.024
poly(target_num, 3)3:factor1:parent2   1.099314   1.731690   0.635
poly(target_num, 3)1:factor2:parent2   9.409337   1.731690   5.434
poly(target_num, 3)2:factor2:parent2  -2.361622   1.731690  -1.364
poly(target_num, 3)3:factor2:parent2  -1.057673   1.731690  -0.611
poly(target_num, 3)1:factor3:parent2  -8.087893   1.731690  -4.671
poly(target_num, 3)2:factor3:parent2   6.669873   1.731690   3.852
poly(target_num, 3)3:factor3:parent2  -4.830063   1.731690  -2.789

Correlation matrix not shown by default, as p = 32 > 12.
Use print(x, correlation=TRUE)  or
     vcov(x)     if you need it

A lot to sort through here, but here are some observations:

  • Collapsing across factors, it seems like parents might perceive exaggerated non-linearities? (poly(target_num, 3)2:parent2 and poly(target_num, 3)3:parent2)
  • Compared to collapsing across factors, not a lot of additional parent vs. non-parent differences in negative emotions (factor 1)
  • Compared to collapsing across factors, parents perceived more dramatic (linear) growth in cognition/control (factor 2; poly(target_num, 3)1:factor2:parent2)
  • Compared to collapsing across factors, in the domain of bodily sensations (factor 3), parents perceived less growth (poly(target_num, 3)1:factor3:parent2). I’m not sure how to interpret the differences in non-linearity here.

You could imagine re-running any of these with a square-root transformation on target age, and/or with the ‘summary scores’ by category, but I’m not going to do that right now.

Study 1

Preliminaries

parent_counts_S1 <- demo_S1 %>% 
  distinct(ResponseId, Parent) %>% 
  rename(subid = ResponseId, parent = Parent) %>%
  count(parent) %>% 
  mutate(proportion = n/sum(n))
knitr::kable(parent_counts_S1, digits = 3)
parent n proportion
No 147 0.653
Yes 77 0.342
NA 1 0.004
scores_S1 <- efa_S1$scores %>%
  data.frame() %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(factor, score, -c(subid, starts_with("target"))) %>%
  left_join(demo_S1 %>% distinct(ResponseId, Parent) %>%
              rename(subid = ResponseId, parent = Parent) %>%
              mutate(subid = as.character(subid))) %>%
  mutate(factor_names = recode_factor(factor,
                                      "MR4" = "Negative emotions (S1 F4)",
                                      "MR1" = "Cognition & control (S1 F1)",
                                      "MR2" = "Bodily sensations (S1 F2)",
                                      "MR3" = "Positive/social emotions (S1 F3)"),
         factor = factor(factor))
Joining, by = "subid"

Plots

Factor scores

# bootstrapped means and 95% CIs
d_parent_boot_S1 <- scores_S1 %>%
  filter(!is.na(parent)) %>%
  group_by(parent, target, target_num, target_ord, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup() %>%
  data.frame()
scores_S1 %>%
  filter(!is.na(parent)) %>%
  ggplot(aes(x = target_num, y = score, color = parent)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_parent_boot_S1,
            position = position_dodge(width = 5),
            aes(y = mean, group = parent)) +
  geom_pointrange(data = d_parent_boot_S1, 
                  position = position_dodge(width = 5),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = parent), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by parent status (STUDY 1)",
       subtitle = "Exact age, untransformed",
       color = "parent status: ",
       x = "target age (months)", y = "score (NOTE: scales differ)")

I won’t bother to re-plot with different treatments of age, since there are only three target ages here.

Category ‘summary scores’

# make new dataframe
d_cat_S1 <- d_all_S1 %>%
  rename(subid_target = X) %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(capacity, response, -c(subid, starts_with("target"))) %>%
  left_join(factors_S2) %>%
  left_join(demo_S1 %>%
              select(ResponseId, Parent) %>%
              rename(subid = ResponseId, parent = Parent) %>%
              mutate(subid = as.character(subid))) %>%
  filter(!is.na(factor)) # drop extra items from S1 not in S2
Joining, by = "capacity"
Joining, by = "subid"

And get an average “score” for each of these factors for each participant:

d_cat_scored_S1 <- d_cat_S1 %>%
  group_by(subid, parent, 
           target, target_num, target_ord, 
           factor, factor_names) %>%
  summarise(score = mean(response, na.rm = T)) %>%
  ungroup()
# bootstrapped means and 95% CIs
d_cat_parent_scored_boot_S1 <- d_cat_scored_S1 %>%
  filter(!is.na(parent)) %>%
  group_by(parent, target, target_num, target_ord, factor, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup()
ggplot(d_cat_parent_scored_boot_S1,
       aes(x = target_num, y = score, color = parent)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_parent_scored_boot_S1,
            position = position_dodge(width = 5),
            aes(y = mean, group = parent)) +
  geom_pointrange(data = d_cat_parent_scored_boot_S1,
                  position = position_dodge(width = 5),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, untransformed",
       x = "target age (months)",
       y = "score (NOTE: scales differ)")

Looking quickly at these two visualizations of Study 1, I’d say that there’s a hint of the same patterns in the domains of negative emotions and positive social emotions (parents attributed more than non-parents, especially at 9 months), and in cognition/control (parents attributed more than non-parents at 5 years). So, generally consistent?

I won’t run regression analyses just now.

Men vs. women

Study 2

Preliminaries

d_gender <- d_all %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(capacity, response, -c(subid, starts_with("target"))) %>%
  left_join(d_demo %>%
              select(ResponseId, GenderSex) %>%
              rename(subid = ResponseId, gender = GenderSex) %>%
              mutate(subid = as.character(subid)))
Joining, by = "subid"
gender_counts <- d_demo %>% 
  distinct(ResponseId, GenderSex) %>% 
  rename(subid = ResponseId, gender = GenderSex) %>%
  count(gender) %>% 
  mutate(proportion = n/sum(n))
knitr::kable(gender_counts, digits = 3)
gender n proportion
Female 123 0.519
Male 114 0.481
scores_S2 <- efa_S2$scores %>%
  data.frame() %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(factor, score, -c(subid, starts_with("target"))) %>%
  left_join(d_gender %>% distinct(subid, gender)) %>%
  left_join(d_cat %>% distinct(factor, factor_names)) %>%
  mutate(factor = factor(factor), gender = factor(gender))
Joining, by = "subid"
Joining, by = "factor"
Column `factor` joining character vector and factor, coercing into character vector

Plots

Factor scores

# bootstrapped means and 95% CIs
d_gender_boot <- scores_S2 %>%
  filter(!is.na(gender)) %>%
  group_by(gender, target, target_num, target_ord, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup() %>%
  data.frame()
scores_S2 %>%
  filter(!is.na(gender)) %>%
  ggplot(aes(x = target_num, y = score, color = gender)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_gender_boot, aes(y = mean, group = gender)) +
  geom_pointrange(data = d_gender_boot, fatten = 1.5, # note: too close to dodge
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = gender), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by participant gender",
       subtitle = "Exact age, untransformed",
       color = "gender: ",
       x = "target age (months)", y = "score (NOTE: scales differ)")

scores_S2 %>%
  filter(!is.na(gender)) %>%
  ggplot(aes(x = target_num, y = score, color = gender)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_gender_boot, aes(y = mean, group = gender),
            position = position_dodge(width = 0.3)) +
  geom_pointrange(data = d_gender_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper),
                  position = position_dodge(width = 0.3)) +
  # geom_smooth(aes(group = gender), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12), trans = "sqrt") +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by participant gender",
       subtitle = "Exact age, square-root transformed",
       color = "participant gender: ",
       x = "age after square-root transformation (months)", 
       y = "score (NOTE: scales differ)")

scores_S2 %>%
  filter(!is.na(gender)) %>%
  ggplot(aes(x = target_ord, y = score, color = gender)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_gender_boot, aes(y = mean, group = gender),
            position = position_dodge(width = 0.5)) +
  geom_pointrange(data = d_gender_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper),
                  position = position_dodge(width = 0.5)) +
  # geom_smooth(aes(group = gender), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by participant gender",
       subtitle = "Age as ordinal variable",
       color = "participant gender: ",
       x = "age (ordinal)", 
       y = "score (NOTE: scales differ)")

Category ‘summary scores’

# bootstrapped means and 95% CIs
d_cat_gender_scored_boot <- d_cat_scored %>%
  left_join(d_demo %>% distinct(ResponseId, GenderSex) %>%
              mutate(ResponseId = as.character(ResponseId)) %>%
              rename(subid = ResponseId, gender = GenderSex)) %>%
  filter(!is.na(gender)) %>%
  group_by(gender, target, target_num, target_ord, factor, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup()
Joining, by = "subid"
ggplot(d_cat_gender_scored_boot,
       aes(x = target_num, y = score, color = gender)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_gender_scored_boot, 
            aes(y = mean, group = gender)) +
  geom_pointrange(data = d_cat_gender_scored_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, untransformed",
       x = "target age (months)",
       y = "score (NOTE: scales differ)")

ggplot(d_cat_gender_scored_boot,
       aes(x = target_num, y = score, color = gender)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_gender_scored_boot, 
            aes(y = mean, group = gender)) +
  geom_pointrange(data = d_cat_gender_scored_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12), trans = "sqrt") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, square-root transformation",
       x = "age after square-root transformation (months)",
       y = "score (NOTE: scales differ)")

ggplot(d_cat_gender_scored_boot,
       aes(x = target_ord, y = score, color = gender)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_gender_scored_boot, 
            aes(y = mean, group = gender)) +
  geom_pointrange(data = d_cat_gender_scored_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Age as an ordinal variable",
       x = "age (ordinal)",
       y = "score (NOTE: scales differ)")

All of these visualizations suggest that, relative to women, men tended to perceive fewer abilities in the negative emotions domain (across the age range) and in the bodily sensations domain (especially for very young infants), and perhaps in the positive/social emotions domain (for toddlers). In contrast, if anythign men seemed to perceive more cognition & control abilities in the middle age ranges (~ 1 year). None of these are huge effects, but they are intriguing.

Regressions

There are many ways that we could choose to model this - I’ll try out the factor scores first, adapting our primary regression models (not in this notebook).

contrasts(scores_S2$gender) <- contr.treatment(2, base = 1) # baseline: FEMALE
contrasts(scores_S2$factor) <- contr.sum(4)
r2 <- lmer(score ~ target_num * factor * gender
           + (target_num + factor | subid),
           scores_S2 %>%
             mutate(target_num = target_num/12))
summary(r2)
Linear mixed model fit by REML ['lmerMod']
Formula: score ~ target_num * factor * gender + (target_num + factor |  
    subid)
   Data: scores_S2 %>% mutate(target_num = target_num/12)

REML criterion at convergence: 22684.2

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-9.3855 -0.4361  0.0520  0.5098  5.3101 

Random effects:
 Groups   Name        Variance Std.Dev. Corr                   
 subid    (Intercept) 0.34624  0.5884                          
          target_num  0.01648  0.1284   -0.73                  
          factor1     0.18436  0.4294    0.49 -0.41            
          factor2     0.22582  0.4752   -0.65  0.57 -0.39      
          factor3     0.25876  0.5087    0.24  0.00 -0.23 -0.61
 Residual             0.29011  0.5386                          
Number of obs: 12324, groups:  subid, 237

Fixed effects:
                            Estimate Std. Error t value
(Intercept)                -0.352499   0.053820  -6.550
target_num                  0.279569   0.012339  22.658
factor1                     0.198080   0.041761   4.743
factor2                    -0.398918   0.045618  -8.745
factor3                     0.304166   0.048464   6.276
gender2                    -0.085230   0.077601  -1.098
target_num:factor1         -0.073166   0.007398  -9.890
target_num:factor2          0.232390   0.007398  31.413
target_num:factor3         -0.205753   0.007398 -27.813
target_num:gender2         -0.001484   0.017791  -0.083
factor1:gender2            -0.236684   0.060213  -3.931
factor2:gender2             0.211000   0.065775   3.208
factor3:gender2            -0.080956   0.069878  -1.159
target_num:factor1:gender2  0.028011   0.010667   2.626
target_num:factor2:gender2 -0.044941   0.010667  -4.213
target_num:factor3:gender2  0.037002   0.010667   3.469

Correlation matrix not shown by default, as p = 16 > 12.
Use print(x, correlation=TRUE)  or
     vcov(x)     if you need it

The last six coefficients here are where the action is: According to this model, the difference between male and female in overall mental capacity attributions (gender2, which is not significant collapsing across factors and targets) is exaggerated in the domain of negative emotions (factor1:gender2), diminished in the domain of cognition and control (factor2:gender2), and neither diminshed nor exaggerated in the domain of bodily sensations (factor3:gender2). Meanwhile, the difference between male and female in perceived developmental trajectories (target_num:gender2, which is not significant collapsing across factors) is (likewise) exaggerated in the domain of negative emotions (target_num:factor1:gender2), diminished in the domain of cognition and control (target_num:factor2:gender2) and exaggerated in the domain of bodily sensations (target_num:factor3:gender2).

Let’s try adding polynomial effects:

r3 <- lmer(score ~ poly(target_num, 3) * factor * gender
           + (poly(target_num, 1) + factor | subid),
           scores_S2 %>%
             mutate(target_num = target_num/12))
summary(r3)
Linear mixed model fit by REML ['lmerMod']
Formula: score ~ poly(target_num, 3) * factor * gender + (poly(target_num,  
    1) + factor | subid)
   Data: scores_S2 %>% mutate(target_num = target_num/12)

REML criterion at convergence: 20032.2

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-10.2922  -0.4698   0.0025   0.5288   5.8429 

Random effects:
 Groups   Name                Variance Std.Dev. Corr                   
 subid    (Intercept)           0.2251  0.4745                         
          poly(target_num, 1) 519.0181 22.7820  -0.51                  
          factor1               0.1878  0.4333   0.45 -0.40            
          factor2               0.2292  0.4788  -0.59  0.56 -0.39      
          factor3               0.2622  0.5120   0.29  0.00 -0.23 -0.61
 Residual                       0.2312  0.4809                         
Number of obs: 12324, groups:  subid, 237

Fixed effects:
                                      Estimate Std. Error t value
(Intercept)                            0.04200    0.04320   0.972
poly(target_num, 3)1                  48.93792    2.15991  22.657
poly(target_num, 3)2                 -19.76380    0.66749 -29.609
poly(target_num, 3)3                   8.89729    0.66749  13.329
factor1                                0.09484    0.04043   2.345
factor2                               -0.07099    0.04441  -1.599
factor3                                0.01383    0.04733   0.292
gender2                               -0.08732    0.06229  -1.402
poly(target_num, 3)1:factor1         -12.80752    1.15613 -11.078
poly(target_num, 3)2:factor1           2.82583    1.15613   2.444
poly(target_num, 3)3:factor1          -0.97761    1.15613  -0.846
poly(target_num, 3)1:factor2          40.67937    1.15613  35.186
poly(target_num, 3)2:factor2           3.21977    1.15613   2.785
poly(target_num, 3)3:factor2          -7.38714    1.15613  -6.390
poly(target_num, 3)1:factor3         -36.01663    1.15613 -31.153
poly(target_num, 3)2:factor3          13.88965    1.15613  12.014
poly(target_num, 3)3:factor3          -7.53568    1.15613  -6.518
poly(target_num, 3)1:gender2          -0.25972    3.11428  -0.083
poly(target_num, 3)2:gender2          -0.60651    0.96243  -0.630
poly(target_num, 3)3:gender2           0.27380    0.96243   0.284
factor1:gender2                       -0.19716    0.05830  -3.382
factor2:gender2                        0.14758    0.06403   2.305
factor3:gender2                       -0.02874    0.06824  -0.421
poly(target_num, 3)1:factor1:gender2   4.90328    1.66698   2.941
poly(target_num, 3)2:factor1:gender2   0.95398    1.66698   0.572
poly(target_num, 3)3:factor1:gender2  -0.58404    1.66698  -0.350
poly(target_num, 3)1:factor2:gender2  -7.86688    1.66698  -4.719
poly(target_num, 3)2:factor2:gender2  -1.80751    1.66698  -1.084
poly(target_num, 3)3:factor2:gender2   1.33095    1.66698   0.798
poly(target_num, 3)1:factor3:gender2   6.47711    1.66698   3.886
poly(target_num, 3)2:factor3:gender2  -5.73172    1.66698  -3.438
poly(target_num, 3)3:factor3:gender2   5.11585    1.66698   3.069

Correlation matrix not shown by default, as p = 32 > 12.
Use print(x, correlation=TRUE)  or
     vcov(x)     if you need it

A lot to sort through here, but here are some observations:

  • Most of the differences across genders seem to be in the linear (not quadratic or cubic) components
  • The one exception to this is in the bodily sensations domain (factor 3), where men seem to have perceived the shape of the developmental trajectory differently both in terms of its quadratic (poly(target_num, 2)1:factor2:gender2) and its cubic (poly(target_num, 3)1:factor2:gender2) components. But I’m having a hard time interpreting the coefficients at this point.

You could imagine re-running any of these with a square-root transformation on target age, and/or with the ‘summary scores’ by category, but I’m not going to do that right now.

Study 1

Preliminaries

gender_counts_S1 <- demo_S1 %>% 
  distinct(ResponseId, GenderSex) %>% 
  rename(subid = ResponseId, gender = GenderSex) %>%
  count(gender) %>% 
  mutate(proportion = n/sum(n))
knitr::kable(gender_counts_S1, digits = 3)
gender n proportion
Female 96 0.427
Male 127 0.564
Other (please describe) 1 0.004
Prefer not to say 1 0.004
scores_S1 <- efa_S1$scores %>%
  data.frame() %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(factor, score, -c(subid, starts_with("target"))) %>%
  left_join(demo_S1 %>% distinct(ResponseId, GenderSex) %>%
              rename(subid = ResponseId, gender = GenderSex) %>%
              mutate(subid = as.character(subid))) %>%
  mutate(factor_names = recode_factor(factor,
                                      "MR4" = "Negative emotions (S1 F4)",
                                      "MR1" = "Cognition & control (S1 F1)",
                                      "MR2" = "Bodily sensations (S1 F2)",
                                      "MR3" = "Positive/social emotions (S1 F3)"),
         factor = factor(factor))
Joining, by = "subid"

Plots

Factor scores

# bootstrapped means and 95% CIs
d_gender_boot_S1 <- scores_S1 %>%
  filter(!is.na(gender)) %>%
  group_by(gender, target, target_num, target_ord, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup() %>%
  data.frame()
scores_S1 %>%
  filter(gender %in% c("Female", "Male")) %>%
  ggplot(aes(x = target_num, y = score, color = gender)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_gender_boot_S1 %>%
              filter(gender %in% c("Female", "Male")),
            position = position_dodge(width = 5),
            aes(y = mean, group = gender)) +
  geom_pointrange(data = d_gender_boot_S1 %>%
                    filter(gender %in% c("Female", "Male")), 
                  position = position_dodge(width = 5),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = gender), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by participant gender (STUDY 1)",
       subtitle = "Exact age, untransformed",
       color = "participant gender: ",
       x = "target age (months)", y = "score (NOTE: scales differ)")

I won’t bother to re-plot with different treatments of age, since there are only three target ages here.

Category ‘summary scores’

# make new dataframe
d_cat_S1 <- d_all_S1 %>%
  rename(subid_target = X) %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(capacity, response, -c(subid, starts_with("target"))) %>%
  left_join(factors_S2) %>%
  left_join(demo_S1 %>%
              select(ResponseId, GenderSex) %>%
              rename(subid = ResponseId, gender = GenderSex) %>%
              mutate(subid = as.character(subid))) %>%
  filter(!is.na(factor)) # drop extra items from S1 not in S2
Joining, by = "capacity"
Joining, by = "subid"

And get an average “score” for each of these factors for each participant:

d_cat_scored_S1 <- d_cat_S1 %>%
  group_by(subid, gender, 
           target, target_num, target_ord, 
           factor, factor_names) %>%
  summarise(score = mean(response, na.rm = T)) %>%
  ungroup()
# bootstrapped means and 95% CIs
d_cat_gender_scored_boot_S1 <- d_cat_scored_S1 %>%
  filter(!is.na(gender)) %>%
  group_by(gender, target, target_num, target_ord, factor, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup()
ggplot(d_cat_gender_scored_boot_S1 %>%
         filter(gender %in% c("Female", "Male")),
       aes(x = target_num, y = score, color = gender)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_gender_scored_boot_S1 %>%
              filter(gender %in% c("Female", "Male")),
            position = position_dodge(width = 5),
            aes(y = mean, group = gender)) +
  geom_pointrange(data = d_cat_gender_scored_boot_S1 %>%
                    filter(gender %in% c("Female", "Male")),
                  position = position_dodge(width = 5),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, untransformed",
       x = "target age (months)",
       y = "score (NOTE: scales differ)")

ggplot(d_cat_gender_scored_boot_S1 %>%
         filter(gender %in% c("Female", "Male")),
       aes(x = target_num, y = score, color = gender)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_gender_scored_boot_S1 %>%
              filter(gender %in% c("Female", "Male")),
            position = position_dodge(width = 1),
            aes(y = mean, group = gender)) +
  geom_pointrange(data = d_cat_gender_scored_boot_S1 %>%
                    filter(gender %in% c("Female", "Male")),
                  position = position_dodge(width = 1),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12), trans = "sqrt") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, square-root transformed",
       x = "age after square-root transformation (months)",
       y = "score (NOTE: scales differ)")

ggplot(d_cat_gender_scored_boot_S1 %>%
         filter(gender %in% c("Female", "Male")),
       aes(x = target_ord, y = score, color = gender)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_gender_scored_boot_S1 %>%
              filter(gender %in% c("Female", "Male")),
            position = position_dodge(width = 0.5),
            aes(y = mean, group = gender)) +
  geom_pointrange(data = d_cat_gender_scored_boot_S1 %>%
                    filter(gender %in% c("Female", "Male")),
                  position = position_dodge(width = 0.5),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  # scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "age (ordinal)",
       x = "target",
       y = "score (NOTE: scales differ)")

Looking quickly at these two visualizations of Study 1, I’d say that they are similar to the visualizations for Study 2, both in the negative emotions and bodily domains. There a hint of more of a difference here in the positive & social emotions domain. So, generally consistent?

I won’t run regression analyses just now.

Higher vs. lower levels of education

Study 2

Preliminaries

d_edu <- d_all %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(capacity, response, -c(subid, starts_with("target"))) %>%
  left_join(d_demo %>%
              select(ResponseId, Education) %>%
              mutate(edu = case_when(as.numeric(Education) < 8 ~ "less than a BA",
                                     as.numeric(Education) >= 8 ~ "BA or more"),
                     edu = factor(edu, 
                                  levels = c("less than a BA",
                                             "BA or more"))) %>%
              rename(subid = ResponseId) %>%
              mutate(subid = as.character(subid)))
Joining, by = "subid"
edu_counts <- d_demo %>% 
  distinct(ResponseId, Education) %>% 
  rename(subid = ResponseId, edu = Education) %>%
  count(edu) %>% 
  mutate(proportion = n/sum(n))
knitr::kable(edu_counts, digits = 3)
edu n proportion
Some high school, no diploma 2 0.008
High school graduate, diploma or equivalent (including GED) 31 0.131
Some college credit, no degree 61 0.257
Trade school, technical school, or vocational school 11 0.046
Associate's degree (for example, AA, AS) 26 0.110
Bachelor's degree (for example, BA, BS) 80 0.338
Master's degree (for example, MA, MS) 25 0.105
Doctor or professional degree (for example, PhD, JD, MD, MBA) 1 0.004
scores_S2 <- efa_S2$scores %>%
  data.frame() %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(factor, score, -c(subid, starts_with("target"))) %>%
  left_join(d_edu %>% distinct(subid, edu)) %>%
  left_join(d_cat %>% distinct(factor, factor_names)) %>%
  mutate(factor = factor(factor), edu = factor(edu))
Joining, by = "subid"
Joining, by = "factor"
Column `factor` joining character vector and factor, coercing into character vector

Plots

Factor scores

# bootstrapped means and 95% CIs
d_edu_boot <- scores_S2 %>%
  filter(!is.na(edu)) %>%
  group_by(edu, target, target_num, target_ord, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup() %>%
  data.frame()
scores_S2 %>%
  filter(!is.na(edu)) %>%
  ggplot(aes(x = target_num, y = score, color = edu)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_edu_boot, aes(y = mean, group = edu)) +
  geom_pointrange(data = d_edu_boot, fatten = 1.5, # note: too close to dodge
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = edu), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by participant edu",
       subtitle = "Exact age, untransformed",
       color = "edu: ",
       x = "target age (months)", y = "score (NOTE: scales differ)")

scores_S2 %>%
  filter(!is.na(edu)) %>%
  ggplot(aes(x = target_num, y = score, color = edu)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_edu_boot, aes(y = mean, group = edu),
            position = position_dodge(width = 0.3)) +
  geom_pointrange(data = d_edu_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper),
                  position = position_dodge(width = 0.3)) +
  # geom_smooth(aes(group = edu), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12), trans = "sqrt") +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by participant edu",
       subtitle = "Exact age, square-root transformed",
       color = "participant edu: ",
       x = "age after square-root transformation (months)", 
       y = "score (NOTE: scales differ)")

scores_S2 %>%
  filter(!is.na(edu)) %>%
  ggplot(aes(x = target_ord, y = score, color = edu)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_edu_boot, aes(y = mean, group = edu),
            position = position_dodge(width = 0.5)) +
  geom_pointrange(data = d_edu_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper),
                  position = position_dodge(width = 0.5)) +
  # geom_smooth(aes(group = edu), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by participant edu",
       subtitle = "Age as ordinal variable",
       color = "participant edu: ",
       x = "age (ordinal)", 
       y = "score (NOTE: scales differ)")

Category ‘summary scores’

# bootstrapped means and 95% CIs
d_cat_edu_scored_boot <- d_cat_scored %>%
  left_join(d_demo %>% distinct(ResponseId, Education) %>%
              mutate(ResponseId = as.character(ResponseId),
                     edu = case_when(as.numeric(Education) < 8 ~ "less than a BA",
                                     as.numeric(Education) >= 8 ~ "BA or more"),
                     edu = factor(edu,
                                  levels = c("less than a BA",
                                             "BA or more"))) %>%
              rename(subid = ResponseId)) %>%
  filter(!is.na(edu)) %>%
  group_by(edu, target, target_num, target_ord, factor, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup()
Joining, by = "subid"
ggplot(d_cat_edu_scored_boot,
       aes(x = target_num, y = score, color = edu)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_edu_scored_boot, 
            aes(y = mean, group = edu)) +
  geom_pointrange(data = d_cat_edu_scored_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, untransformed",
       x = "target age (months)",
       y = "score (NOTE: scales differ)")

ggplot(d_cat_edu_scored_boot,
       aes(x = target_num, y = score, color = edu)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_edu_scored_boot, 
            aes(y = mean, group = edu)) +
  geom_pointrange(data = d_cat_edu_scored_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12), trans = "sqrt") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, square-root transformation",
       x = "age after square-root transformation (months)",
       y = "score (NOTE: scales differ)")

ggplot(d_cat_edu_scored_boot,
       aes(x = target_ord, y = score, color = edu)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_edu_scored_boot, 
            aes(y = mean, group = edu)) +
  geom_pointrange(data = d_cat_edu_scored_boot, fatten = 1.5,
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Age as an ordinal variable",
       x = "age (ordinal)",
       y = "score (NOTE: scales differ)")

All of these visualizations suggest that, relative to less educated participants, more educated participants tended to perceive slightly fewer abilities in the negative emotions domain, but were otherwise generally very similar.

Regressions

There are many ways that we could choose to model this - I’ll try out the factor scores first, adapting our primary regression models (not in this notebook).

contrasts(scores_S2$edu) <- contr.treatment(2, base = 1) # baseline: less educated
contrasts(scores_S2$factor) <- contr.sum(4)
r2 <- lmer(score ~ target_num * factor * edu
           + (target_num + factor | subid),
           scores_S2 %>%
             mutate(target_num = target_num/12))
summary(r2)
Linear mixed model fit by REML ['lmerMod']
Formula: score ~ target_num * factor * edu + (target_num + factor | subid)
   Data: scores_S2 %>% mutate(target_num = target_num/12)

REML criterion at convergence: 22726.8

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-9.4244 -0.4335  0.0513  0.5090  5.3716 

Random effects:
 Groups   Name        Variance Std.Dev. Corr                   
 subid    (Intercept) 0.34804  0.5899                          
          target_num  0.01646  0.1283   -0.73                  
          factor1     0.19408  0.4406    0.49 -0.40            
          factor2     0.23103  0.4807   -0.66  0.56 -0.41      
          factor3     0.25862  0.5085    0.24  0.00 -0.21 -0.61
 Residual             0.29081  0.5393                          
Number of obs: 12324, groups:  subid, 237

Fixed effects:
                         Estimate Std. Error t value
(Intercept)             -0.391254   0.052284  -7.483
target_num               0.282154   0.011952  23.607
factor1                  0.081491   0.041379   1.969
factor2                 -0.307750   0.044657  -6.891
factor3                  0.290749   0.046956   6.192
edu2                    -0.005014   0.078179  -0.064
target_num:factor1      -0.054535   0.007177  -7.598
target_num:factor2       0.208371   0.007177  29.033
target_num:factor3      -0.194921   0.007177 -27.159
target_num:edu2         -0.007374   0.017871  -0.413
factor1:edu2             0.006130   0.061873   0.099
factor2:edu2             0.023088   0.066774   0.346
factor3:edu2            -0.057068   0.070211  -0.813
target_num:factor1:edu2 -0.011532   0.010732  -1.075
target_num:factor2:edu2  0.005372   0.010732   0.501
target_num:factor3:edu2  0.015575   0.010732   1.451

Correlation matrix not shown by default, as p = 16 > 12.
Use print(x, correlation=TRUE)  or
     vcov(x)     if you need it

Nada.

Let’s try adding polynomial effects:

r3 <- lmer(score ~ poly(target_num, 3) * factor * edu
           + (poly(target_num, 1) + factor | subid),
           scores_S2 %>%
             mutate(target_num = target_num/12))
summary(r3)
Linear mixed model fit by REML ['lmerMod']
Formula: score ~ poly(target_num, 3) * factor * edu + (poly(target_num,  
    1) + factor | subid)
   Data: scores_S2 %>% mutate(target_num = target_num/12)

REML criterion at convergence: 20092.9

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-10.3685  -0.4600   0.0056   0.5311   5.9055 

Random effects:
 Groups   Name                Variance Std.Dev. Corr                   
 subid    (Intercept)           0.2270  0.4764                         
          poly(target_num, 1) 518.4274 22.7690  -0.51                  
          factor1               0.1975  0.4444   0.45 -0.39            
          factor2               0.2344  0.4842  -0.60  0.55 -0.41      
          factor3               0.2620  0.5119   0.29  0.00 -0.22 -0.61
 Residual                       0.2322  0.4818                         
Number of obs: 12324, groups:  subid, 237

Fixed effects:
                                    Estimate Std. Error t value
(Intercept)                         0.006897   0.042031   0.164
poly(target_num, 3)1               49.390345   2.092247  23.606
poly(target_num, 3)2              -21.317213   0.648102 -32.892
poly(target_num, 3)3               10.204882   0.648102  15.746
factor1                             0.004537   0.040120   0.113
factor2                            -0.013717   0.043494  -0.315
factor3                             0.015694   0.045850   0.342
edu2                               -0.015421   0.062848  -0.245
poly(target_num, 3)1:factor1       -9.546136   1.122546  -8.504
poly(target_num, 3)2:factor1        2.830921   1.122546   2.522
poly(target_num, 3)3:factor1       -0.776043   1.122546  -0.691
poly(target_num, 3)1:factor2       36.474744   1.122546  32.493
poly(target_num, 3)2:factor2        3.825457   1.122546   3.408
poly(target_num, 3)3:factor2       -7.834359   1.122546  -6.979
poly(target_num, 3)1:factor3      -34.120438   1.122546 -30.396
poly(target_num, 3)2:factor3       11.638223   1.122546  10.368
poly(target_num, 3)3:factor3       -5.846249   1.122546  -5.208
poly(target_num, 3)1:edu2          -1.290868   3.128486  -0.413
poly(target_num, 3)2:edu2           2.820908   0.969091   2.911
poly(target_num, 3)3:edu2          -2.629115   0.969091  -2.713
factor1:edu2                       -0.010143   0.059991  -0.169
factor2:edu2                        0.030668   0.065035   0.472
factor3:edu2                       -0.035090   0.068559  -0.512
poly(target_num, 3)1:factor1:edu2  -2.018615   1.678516  -1.203
poly(target_num, 3)2:factor1:edu2   1.014589   1.678516   0.604
poly(target_num, 3)3:factor1:edu2  -1.078782   1.678516  -0.643
poly(target_num, 3)1:factor2:edu2   0.940291   1.678516   0.560
poly(target_num, 3)2:factor2:edu2  -3.298146   1.678516  -1.965
poly(target_num, 3)3:factor2:edu2   2.431313   1.678516   1.448
poly(target_num, 3)1:factor3:edu2   2.726340   1.678516   1.624
poly(target_num, 3)2:factor3:edu2  -1.130454   1.678516  -0.673
poly(target_num, 3)3:factor3:edu2   1.724635   1.678516   1.027

Correlation matrix not shown by default, as p = 32 > 12.
Use print(x, correlation=TRUE)  or
     vcov(x)     if you need it

Again, nothing substantial - some indications of some education-related differences in perceptions of non-linear effects? But hard to make too much sense of that.

You could imagine re-running any of these with a square-root transformation on target age, and/or with the ‘summary scores’ by category, but I’m not going to do that right now.

Study 1

Preliminaries

edu_counts_S1 <- demo_S1 %>% 
  distinct(ResponseId, Education) %>% 
  mutate(edu = case_when(
    as.numeric(Education) %in% c(1, 4, 6, 7, 8) ~ "less than a BA",
    as.numeric(Education) %in% c(2, 3, 5) ~ "BA or more"),
         edu = factor(edu, levels = c("less than a BA", "BA or more"))) %>%
  rename(subid = ResponseId) %>%
  count(edu) %>% 
  mutate(proportion = n/sum(n))
knitr::kable(edu_counts_S1, digits = 3)
edu n proportion
less than a BA 132 0.587
BA or more 93 0.413
scores_S1 <- efa_S1$scores %>%
  data.frame() %>%
  rownames_to_column("subid_target") %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(factor, score, -c(subid, starts_with("target"))) %>%
  left_join(demo_S1 %>% distinct(ResponseId, Education) %>%
              mutate(edu = case_when(
                as.numeric(Education) %in% c(1, 4, 6, 7, 8) ~ "less than a BA",
                as.numeric(Education) %in% c(2, 3, 5) ~ "BA or more"),
                edu = factor(edu, levels = c("less than a BA", "BA or more"))) %>%
              rename(subid = ResponseId) %>%
              mutate(subid = as.character(subid))) %>%
  mutate(factor_names = recode_factor(factor,
                                      "MR4" = "Negative emotions (S1 F4)",
                                      "MR1" = "Cognition & control (S1 F1)",
                                      "MR2" = "Bodily sensations (S1 F2)",
                                      "MR3" = "Positive/social emotions (S1 F3)"),
         factor = factor(factor))
Joining, by = "subid"

Plots

Factor scores

# bootstrapped means and 95% CIs
d_edu_boot_S1 <- scores_S1 %>%
  filter(!is.na(edu)) %>%
  group_by(edu, target, target_num, target_ord, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup() %>%
  data.frame()
scores_S1 %>%
  filter(!is.na(edu)) %>%
  ggplot(aes(x = target_num, y = score, color = edu)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.05) +
  geom_line(data = d_edu_boot_S1 %>%
              filter(!is.na(edu)),
            position = position_dodge(width = 5),
            aes(y = mean, group = edu)) +
  geom_pointrange(data = d_edu_boot_S1 %>%
                    filter(!is.na(edu)), 
                  position = position_dodge(width = 5),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = edu), #color = "black",
  #             method = "lm", formula = "y ~ poly(x, 3)") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(-10, 10, 0.5)) +
  labs(title = "Developmental trajectories of factor scores, by participant education (STUDY 1)",
       subtitle = "Exact age, untransformed",
       color = "participant edu: ",
       x = "target age (months)", y = "score (NOTE: scales differ)")

I won’t bother to re-plot with different treatments of age, since there are only three target ages here.

Category ‘summary scores’

# make new dataframe
d_cat_S1 <- d_all_S1 %>%
  rename(subid_target = X) %>%
  mutate(subid = gsub("_.*$", "", subid_target),
         target = gsub("^.*_", "", subid_target)) %>%
  select(-subid_target) %>%
  mutate(target_num = recode(target,
                             "target00mo" = 0,
                             "target0Xmo" = 4/30,
                             "target01mo" = 1,
                             "target02mo" = 2,
                             "target04mo" = 4,
                             "target06mo" = 6,
                             "target09mo" = 9,
                             "target12mo" = 12,
                             "target18mo" = 18,
                             "target24mo" = 24,
                             "target36mo" = 36,
                             "target48mo" = 48,
                             "target60mo" = 60),
         target_ord = recode_factor(target,
                                    "target00mo" = "newborns",
                                    "target0Xmo" = "4-day-olds",
                                    "target01mo" = "1-month-olds",
                                    "target02mo" = "2-month-olds",
                                    "target04mo" = "4-month-olds",
                                    "target06mo" = "6-month-olds",
                                    "target09mo" = "9-month-olds",
                                    "target12mo" = "12-month-olds",
                                    "target18mo" = "18-month-olds",
                                    "target24mo" = "2-year-olds",
                                    "target36mo" = "3-year-olds",
                                    "target48mo" = "4-year-olds",
                                    "target60mo" = "5-year-olds")) %>%
  gather(capacity, response, -c(subid, starts_with("target"))) %>%
  left_join(factors_S2) %>%
  left_join(demo_S1 %>%
              select(ResponseId, Education) %>%
              mutate(edu = case_when(
                as.numeric(Education) %in% c(1, 4, 6, 7, 8) ~ "less than a BA",
                as.numeric(Education) %in% c(2, 3, 5) ~ "BA or more"),
                edu = factor(edu, levels = c("less than a BA", "BA or more"))) %>%
              rename(subid = ResponseId) %>%
              mutate(subid = as.character(subid))) %>%
  filter(!is.na(factor)) # drop extra items from S1 not in S2
Joining, by = "capacity"
Joining, by = "subid"

And get an average “score” for each of these factors for each participant:

d_cat_scored_S1 <- d_cat_S1 %>%
  group_by(subid, edu, 
           target, target_num, target_ord, 
           factor, factor_names) %>%
  summarise(score = mean(response, na.rm = T)) %>%
  ungroup()
# bootstrapped means and 95% CIs
d_cat_edu_scored_boot_S1 <- d_cat_scored_S1 %>%
  filter(!is.na(edu)) %>%
  group_by(edu, target, target_num, target_ord, factor, factor_names) %>%
  multi_boot_standard("score") %>%
  ungroup()
ggplot(d_cat_edu_scored_boot_S1 %>%
         filter(!is.na(edu)),
       aes(x = target_num, y = score, color = edu)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_edu_scored_boot_S1 %>%
              filter(!is.na(edu)),
            position = position_dodge(width = 5),
            aes(y = mean, group = edu)) +
  geom_pointrange(data = d_cat_edu_scored_boot_S1 %>%
                    filter(!is.na(edu)),
                  position = position_dodge(width = 5),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, untransformed",
       x = "target age (months)",
       y = "score (NOTE: scales differ)")

ggplot(d_cat_edu_scored_boot_S1 %>%
         filter(!is.na(edu)),
       aes(x = target_num, y = score, color = edu)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_edu_scored_boot_S1 %>%
              filter(!is.na(edu)),
            position = position_dodge(width = 1),
            aes(y = mean, group = edu)) +
  geom_pointrange(data = d_cat_edu_scored_boot_S1 %>%
                    filter(!is.na(edu)),
                  position = position_dodge(width = 1),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Paired") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  scale_x_continuous(breaks = seq(0, 60, 12), trans = "sqrt") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "Exact age, square-root transformed",
       x = "age after square-root transformation (months)",
       y = "score (NOTE: scales differ)")

ggplot(d_cat_edu_scored_boot_S1 %>%
         filter(edu %in% c("Female", "Male")),
       aes(x = target_ord, y = score, color = edu)) +
  facet_wrap(~ factor_names, ncol = 4, scales = "free") +
  # geom_line(aes(group = subid), alpha = 0.15) +
  geom_line(data = d_cat_edu_scored_boot_S1 %>%
              filter(edu %in% c("Female", "Male")),
            position = position_dodge(width = 0.5),
            aes(y = mean, group = edu)) +
  geom_pointrange(data = d_cat_edu_scored_boot_S1 %>%
                    filter(edu %in% c("Female", "Male")),
                  position = position_dodge(width = 0.5),
                  aes(y = mean, ymin = ci_lower, ymax = ci_upper)) +
  # geom_smooth(aes(group = factor_names),
  #             method = "lm", formula = "y ~ poly(x, 3)",
  #             color = "black") +
  scale_color_brewer(palette = "Set1") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        legend.position = "bottom") +
  # scale_x_continuous(breaks = seq(0, 60, 12)) +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(title = "Developmental trajectories of category 'summary scores'",
       subtitle = "age (ordinal)",
       x = "target",
       y = "score (NOTE: scales differ)")
Error: Faceting variables must have at least one value

Looking quickly at these two visualizations of Study 1, I’d say that they are similar to the visualizations for Study 2 - perhaps a little more dramatic, especially in the negative emotions and bodily sensations domains.

I won’t run regression analyses just now.

LS0tCnRpdGxlOiAiQmFieSBNZW50YWwgTGlmZTogU3R1ZHkgMiIKc3VidGl0bGU6ICJFeHBsb3JhdG9yeSBhbmFseXNlcyIKZGF0ZTogMjAxOC0xMC0wMwpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQotLS0KCiJCYWJ5IE1lbnRhbCBMaWZlOiBTdHVkeSAyIiB3YXMgY29uZHVjdGVkIG9uIE1UdXJrIG9uIDIwMTgtMDgtMDQuCgpPdXIgcGxhbm5lZCBzYW1wbGUgd2FzIDMwMCBwYXJ0aWNpcGFudHMsIGFuZCB3ZSBhbnRpY2lwYXRlZCB0aGF0IHJvdWdobHkgODAlIG9mIHJlY3J1aXRlZCBwYXJ0aWNpcGFudHMgd291bGQgcGFzcyBhbGwgb2Ygb3VyIGF0dGVudGlvbiBjaGVja3MsIHNvIHdlIGluaXRpYWxseSByZWNydWl0ZWQgMzc4IHBhcnRpY2lwYW50cyAob24gdGhlIGlkZWEgdGhhdCB+ODAlIG9mIDM3OCB+IDMwMCBwYXJ0aWNpcGFudHM7IG5vdGUgdGhhdCBmb3IgYWRtaW5pc3RyYXRpdmUgcHVycG9zZXMgd2UgbmVlZCB0byByZWN1aXQgcGFydGljaXBhbnRzIGluIGJhdGNoZXMgdGhhdCB3ZXJlIGRpdmlzaWJsZSBieSA5KS4gQWZ0ZXIgZmlsdGVyaW5nIG91dCBwYXJ0aWNpcGFudHMgd2hvIGZhaWxlZCBhdCBsZWFzdCBvbmUgb2Ygb3VyIGF0dGVudGlvbiBjaGVja3MsIHdlIGVuZGVkIHVwIHJldGFpbmluZyBmZXdlciB0aGFuIDMwMCBwYXJ0aWNpcGFudHMsIHNvIHdlIHJlY3J1aXRlZCBhbiBhZGRpdGlvbmFsIDE2IHBhcnRpY2lwYW50cyBmb3IgYSB0b3RhbCBvZiAzOTQgcGVvcGxlIHJlY3J1aXRlZC4gQXQgZWFjaCBzdGFnZSwgd2UgcmVjcnVpdGVkIHdvbWVuIGFuZCBtZW4gdGhyb3VnaCBzZXBhcmF0ZSBzdHVkaWVzLCBpbiBob3BlcyBvZiBhY3F1aXJpbmcgYSByb3VnaGx5IGVxdWFsIHNwbGl0IGJldHdlZW4gZ2VuZGVycy4KCkluIHRoZSBlbmQsIHdlIGVuZGVkIHVwIHdpdGggYSBzYW1wbGUgb2YgMzA0IHBhcnRpY2lwYW50cyB3aG8gcGFzc2VkIG91ciBhdHRlbnRpb24gY2hlY2tzLCAyMzcgb2Ygd2hvbSBjYW1lIGZyb20gdW5pcXVlIEdQUyBjb29yZGluYXRlcy4KCioqRm9yIHRoaXMgZmlyc3QgcGFzcywgdGhlc2UgZGF0YSBfZXhjbHVkZV8gcGFydGljaXBhbnRzIHdoZXJlIHRoZXJlIGlzIGFub3RoZXIgcGFydGljaXBhbnQgd2l0aCBhbiBpZGVudGljYWwgc2V0IG9mIEdQUyBjb29yZGluYXRlcyBhcyByZWNvcmRlZCBieSBRdWFsdHJpY3MuKioKCkVhY2ggcGFydGljaXBhbnQgYXNzZXNzZWQgY2hpbGRyZW4ncyBtZW50YWwgY2FwYWNpdGllcyBhdCAxMyB0YXJnZXQgYWdlcyBiZXR3ZWVuIHRoZSBhZ2VzIG9mIDAgYW5kIDUgeWVhcnMuIEZvciBlYWNoIHRhcmdldCwgdGhleSByYXRlZCAyMCBtZW50YWwgY2FwYWNpdGllcyBvbiBhIHNjYWxlIGZyb20gMCAobm90IGF0IGFsbCBjYXBhYmxlKSB0byAxMDAgKGNvbXBsZXRlbHkgY2FwYWJsZSkuIAoKRm9yIG1vcmUgZGV0YWlscyBhYm91dCB0aGUgc3R1ZHksIHNlZSBvdXIgcHJlcmVnaXN0cmF0aW9uIFtoZXJlXShodHRwczovL29zZi5pby9qNzJkZy8pLiAKCioqSGVyZSB3ZSBydW4gc29tZSBleHBsb3JhdG9yeSBhbmFseXNlcyBvbiB0aGVzZSBkYXRhLioqCgpgYGB7cn0KIyBsb2FkIHJlcXVpcmVkIGxpYnJhcmllcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsYW5nY29nKSAjIHNvdXJjZTogaHR0cHM6Ly9naXRodWIuY29tL2xhbmdjb2cvbGFuZ2NvZy1wYWNrYWdlCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkobG1lNCkKbGlicmFyeShrYWJsZUV4dHJhKQoKIyBzZXQgdGhlbWUgZm9yIGdncGxvdHMKdGhlbWVfc2V0KHRoZW1lX2J3KCkpCmBgYAoKYGBge3J9CiMgcnVuIHNvdXJjZSBjb2RlIChleHRyYSBob21lLW1hZGUgZnVuY3Rpb25zKQpzb3VyY2UoIi4vc2NyaXB0cy9tYXhfZmFjdG9yc19lZmEuUiIpCnNvdXJjZSgiLi9zY3JpcHRzL3Bsb3RfZnVuLlIiKQpzb3VyY2UoIi4vc2NyaXB0cy9yZXRlbl9mdW4uUiIpCnNvdXJjZSgiLi9zY3JpcHRzL3RhYmxlX2Z1bi5SIikKc291cmNlKCIuL3NjcmlwdHMvZGF0YV9wcmVwLlIiKQpgYGAKCiMgVHJlYXRpbmcgZmFjdG9ycyBhcyBjYXRlZ29yaWVzCgojIyBQcmVsaW1pbmFyaWVzCgpGaXJzdCwgSSdsbCBkbyB0aGUgZmFjdG9yIGFuYWx5c2lzLCBhbmQgZ2V0IGEgbGlzdCBvZiB0aGUgdG9wIDUgaXRlbXMgYnkgZmFjdG9yOgoKYGBge3J9CiMgbG9hZCBpbiBTMSBlZmEgaW4gY2FzZSB3ZSBuZWVkIGl0CmVmYV9TMSA8LSByZWFkUkRTKCIuLi9zdHVkeSAxL3MxX2VmYS5yZHMiKQpkX2FsbF9TMSA8LSByZWFkLmNzdigiLi4vc3R1ZHkgMS9zMV9kYXRhLmNzdiIpCmRlbW9fUzEgPC0gcmVhZC5jc3YoIi4uL3N0dWR5IDEvczFfZGVtby5jc3YiKQpgYGAKCmBgYHtyfQojIGNvbmR1Y3QgUzIgZWZhCmVmYV9TMiA8LSBmYShkX2FsbCwgbmZhY3RvcnMgPSA0LCByb3RhdGUgPSAib2JsaW1pbiIsIGZtID0gIm1pbnJlcyIsCiAgICAgICAgICAgICBzY29yZXMgPSAidGVuQmVyZ2UiLCBpbXB1dGUgPSAibWVkaWFuIikKYGBgCgpgYGB7cn0KdGFibGVfZnVuKGVmYV9TMiwgbnVtX2l0ZW1zID0gNSwgcG9zX2FicyA9ICJhYnMiKQpgYGAKCk5vdyBJJ2xsIHVzZSB0aGlzIHRvIGRlZmluZSBjYXRlZ29yaWVzIG9mIG1lbnRhbCBjYXBhY2l0aWVzOgoKYGBge3J9CiMgZ2V0IGl0ZW1zIGJ5IGZhY3RvcgpmYWN0b3JzX1MyIDwtIGVmYV9TMiRsb2FkaW5nc1tdICU+JQogIGRhdGEuZnJhbWUoKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oImNhcGFjaXR5IikgJT4lCiAgZ2F0aGVyKGZhY3RvciwgbG9hZGluZywgLWNhcGFjaXR5KSAlPiUKICBncm91cF9ieShjYXBhY2l0eSkgJT4lCiAgdG9wX24oMSwgbG9hZGluZykgJT4lCiAgdW5ncm91cCgpICU+JQogIHNlbGVjdCgtbG9hZGluZykgJT4lCiAgbXV0YXRlKGZhY3Rvcl9uYW1lcyA9IHJlY29kZV9mYWN0b3IoZmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNUjEiID0gIk5lZ2F0aXZlIGVtb3Rpb25zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVIyIiA9ICJDb2duaXRpb24gJiBjb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVIzIiA9ICJCb2RpbHkgc2Vuc2F0aW9ucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1SNCIgPSAiUG9zaXRpdmUvc29jaWFsIGVtb3Rpb25zIiksCiAgICAgICAgIGZhY3RvciA9IGZhY3RvcihmYWN0b3IpKQoKIyBtYWtlIG5ldyBkYXRhZnJhbWUKZF9jYXQgPC0gZF9hbGwgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJzdWJpZF90YXJnZXQiKSAlPiUKICBtdXRhdGUoc3ViaWQgPSBnc3ViKCJfLiokIiwgIiIsIHN1YmlkX3RhcmdldCksCiAgICAgICAgIHRhcmdldCA9IGdzdWIoIl4uKl8iLCAiIiwgc3ViaWRfdGFyZ2V0KSkgJT4lCiAgc2VsZWN0KC1zdWJpZF90YXJnZXQpICU+JQogIG11dGF0ZSh0YXJnZXRfbnVtID0gcmVjb2RlKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDBtbyIgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwWG1vIiA9IDQvMzAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAxbW8iID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDJtbyIgPSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNG1vIiA9IDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA2bW8iID0gNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDltbyIgPSA5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxMm1vIiA9IDEyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxOG1vIiA9IDE4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQyNG1vIiA9IDI0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQzNm1vIiA9IDM2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ0OG1vIiA9IDQ4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ2MG1vIiA9IDYwKSwKICAgICAgICAgdGFyZ2V0X29yZCA9IHJlY29kZV9mYWN0b3IodGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDBtbyIgPSAibmV3Ym9ybnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MFhtbyIgPSAiNC1kYXktb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMW1vIiA9ICIxLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDJtbyIgPSAiMi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA0bW8iID0gIjQtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNm1vIiA9ICI2LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDltbyIgPSAiOS1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDEybW8iID0gIjEyLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MThtbyIgPSAiMTgtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQyNG1vIiA9ICIyLXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQzNm1vIiA9ICIzLXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ0OG1vIiA9ICI0LXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ2MG1vIiA9ICI1LXllYXItb2xkcyIpKSAlPiUKICBnYXRoZXIoY2FwYWNpdHksIHJlc3BvbnNlLCAtYyhzdWJpZCwgc3RhcnRzX3dpdGgoInRhcmdldCIpKSkgJT4lCiAgbGVmdF9qb2luKGZhY3RvcnNfUzIpICU+JQogIGxlZnRfam9pbihkX2RlbW8gJT4lCiAgICAgICAgICAgICAgc2VsZWN0KFJlc3BvbnNlSWQsIFBhcmVudCkgJT4lCiAgICAgICAgICAgICAgcmVuYW1lKHN1YmlkID0gUmVzcG9uc2VJZCwgcGFyZW50ID0gUGFyZW50KSAlPiUKICAgICAgICAgICAgICBtdXRhdGUoc3ViaWQgPSBhcy5jaGFyYWN0ZXIoc3ViaWQpKSkKYGBgCgpDaGVjayByZWxpYWJpbGl0eSAoQ3JvbmJhY2gncyBhbHBoYSk6CgpgYGB7cn0KZF9jYXQgJT4lIAogIGZpbHRlcihmYWN0b3IgPT0gIk1SMSIpICU+JSAKICBtdXRhdGUoc3ViaWRfdGFyZ2V0ID0gcGFzdGUoc3ViaWQsIHRhcmdldCwgc2VwID0gIl8iKSkgJT4lCiAgc2VsZWN0KHN1YmlkX3RhcmdldCwgY2FwYWNpdHksIHJlc3BvbnNlKSAlPiUKICBzcHJlYWQoY2FwYWNpdHksIHJlc3BvbnNlKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoInN1YmlkX3RhcmdldCIpICU+JQogIGNvcigpICU+JQogIGFscGhhKHRpdGxlID0gIk1SMTogTmVnYXRpdmUgZW1vdGlvbnMiKQpgYGAKCmBgYHtyfQpkX2NhdCAlPiUgCiAgZmlsdGVyKGZhY3RvciA9PSAiTVIyIikgJT4lIAogIG11dGF0ZShzdWJpZF90YXJnZXQgPSBwYXN0ZShzdWJpZCwgdGFyZ2V0LCBzZXAgPSAiXyIpKSAlPiUKICBzZWxlY3Qoc3ViaWRfdGFyZ2V0LCBjYXBhY2l0eSwgcmVzcG9uc2UpICU+JQogIHNwcmVhZChjYXBhY2l0eSwgcmVzcG9uc2UpICU+JQogIGNvbHVtbl90b19yb3duYW1lcygic3ViaWRfdGFyZ2V0IikgJT4lCiAgY29yKCkgJT4lCiAgYWxwaGEodGl0bGUgPSAiTVIyOiBDb2duaXRpb24gJiBjb250cm9sIikKYGBgCgpgYGB7cn0KZF9jYXQgJT4lIAogIGZpbHRlcihmYWN0b3IgPT0gIk1SMyIpICU+JSAKICBtdXRhdGUoc3ViaWRfdGFyZ2V0ID0gcGFzdGUoc3ViaWQsIHRhcmdldCwgc2VwID0gIl8iKSkgJT4lCiAgc2VsZWN0KHN1YmlkX3RhcmdldCwgY2FwYWNpdHksIHJlc3BvbnNlKSAlPiUKICBzcHJlYWQoY2FwYWNpdHksIHJlc3BvbnNlKSAlPiUKICBjb2x1bW5fdG9fcm93bmFtZXMoInN1YmlkX3RhcmdldCIpICU+JQogIGNvcigpICU+JQogIGFscGhhKHRpdGxlID0gIk1SMzogQm9kaWx5IHNlbnNhdGlvbnMiKQpgYGAKCmBgYHtyfQpkX2NhdCAlPiUgCiAgZmlsdGVyKGZhY3RvciA9PSAiTVI0IikgJT4lIAogIG11dGF0ZShzdWJpZF90YXJnZXQgPSBwYXN0ZShzdWJpZCwgdGFyZ2V0LCBzZXAgPSAiXyIpKSAlPiUKICBzZWxlY3Qoc3ViaWRfdGFyZ2V0LCBjYXBhY2l0eSwgcmVzcG9uc2UpICU+JQogIHNwcmVhZChjYXBhY2l0eSwgcmVzcG9uc2UpICU+JQogIGNvbHVtbl90b19yb3duYW1lcygic3ViaWRfdGFyZ2V0IikgJT4lCiAgY29yKCkgJT4lCiAgYWxwaGEodGl0bGUgPSAiTVI0OiBTb2NpYWwgYWJpbGl0aWVzICYgcG9zaXRpdmUgZW1vdGlvbnMiKQpgYGAKCkFuZCBnZXQgYW4gYXZlcmFnZSAic2NvcmUiIGZvciBlYWNoIG9mIHRoZXNlIGZhY3RvcnMgZm9yIGVhY2ggcGFydGljaXBhbnQ6CgpgYGB7cn0KZF9jYXRfc2NvcmVkIDwtIGRfY2F0ICU+JQogIGdyb3VwX2J5KHN1YmlkLCBwYXJlbnQsIAogICAgICAgICAgIHRhcmdldCwgdGFyZ2V0X251bSwgdGFyZ2V0X29yZCwgCiAgICAgICAgICAgZmFjdG9yLCBmYWN0b3JfbmFtZXMpICU+JQogIHN1bW1hcmlzZShzY29yZSA9IG1lYW4ocmVzcG9uc2UsIG5hLnJtID0gVCkpICU+JQogIHVuZ3JvdXAoKQpgYGAKCgojIyBQbG90cwoKYGBge3J9CiMgYm9vdHN0cmFwcGVkIG1lYW5zIGFuZCA5NSUgQ0lzCmRfY2F0X3Njb3JlZF9ib290IDwtIGRfY2F0X3Njb3JlZCAlPiUKICBncm91cF9ieSh0YXJnZXQsIHRhcmdldF9udW0sIHRhcmdldF9vcmQsIGZhY3RvciwgZmFjdG9yX25hbWVzKSAlPiUKICBtdWx0aV9ib290X3N0YW5kYXJkKCJzY29yZSIpICU+JQogIHVuZ3JvdXAoKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LCBmaWcuYXNwID0gMC41fQpnZ3Bsb3QoZF9jYXRfc2NvcmVkLAogICAgICAgYWVzKHggPSB0YXJnZXRfbnVtLCB5ID0gc2NvcmUsIGNvbG9yID0gZmFjdG9yX25hbWVzKSkgKwogIGZhY2V0X2dyaWQofiBmYWN0b3JfbmFtZXMpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMTUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfY2F0X3Njb3JlZF9ib290LCBjb2xvciA9ICJibGFjayIsCiAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBmYWN0b3JfbmFtZXMpKSArCiAgZ2VvbV9wb2ludHJhbmdlKGRhdGEgPSBkX2NhdF9zY29yZWRfYm9vdCwgY29sb3IgPSAiYmxhY2siLCBmYXR0ZW4gPSAxLjUsCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBmYWN0b3JfbmFtZXMpLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIsCiAgIyAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIiwgZ3VpZGUgPSAibm9uZSIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDYwLCAxMikpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCB1bnRyYW5zZm9ybWVkIiwKICAgICAgIHggPSAidGFyZ2V0IGFnZSAobW9udGhzKSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAwLjV9CmdncGxvdChkX2NhdF9zY29yZWQsCiAgICAgICBhZXMoeCA9IHRhcmdldF9udW0sIHkgPSBzY29yZSwgY29sb3IgPSBmYWN0b3JfbmFtZXMpKSArCiAgZmFjZXRfZ3JpZCh+IGZhY3Rvcl9uYW1lcykgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzdWJpZCksIGFscGhhID0gMC4xNSkgKwogIGdlb21fbGluZShkYXRhID0gZF9jYXRfc2NvcmVkX2Jvb3QsIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCBncm91cCA9IGZhY3Rvcl9uYW1lcykpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfY2F0X3Njb3JlZF9ib290LCBjb2xvciA9ICJibGFjayIsIGZhdHRlbiA9IDEuNSwKICAgICAgICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCB5bWluID0gY2lfbG93ZXIsIHltYXggPSBjaV91cHBlcikpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGZhY3Rvcl9uYW1lcyksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIiwKICAjICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDIiLCBndWlkZSA9ICJub25lIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSwgdHJhbnMgPSAic3FydCIpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCBzcXVhcmUtcm9vdC10cmFuc2Zvcm1lZCIsCiAgICAgICB4ID0gImFnZSBhZnRlciBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiAobW9udGhzKSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAwLjV9CmdncGxvdChkX2NhdF9zY29yZWQsCiAgICAgICBhZXMoeCA9IHRhcmdldF9vcmQsIHkgPSBzY29yZSwgY29sb3IgPSBmYWN0b3JfbmFtZXMpKSArCiAgZmFjZXRfZ3JpZCh+IGZhY3Rvcl9uYW1lcykgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzdWJpZCksIGFscGhhID0gMC4xNSkgKwogIGdlb21fbGluZShkYXRhID0gZF9jYXRfc2NvcmVkX2Jvb3QsIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCBncm91cCA9IGZhY3Rvcl9uYW1lcykpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfY2F0X3Njb3JlZF9ib290LCBjb2xvciA9ICJibGFjayIsIGZhdHRlbiA9IDEuNSwKICAgICAgICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCB5bWluID0gY2lfbG93ZXIsIHltYXggPSBjaV91cHBlcikpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGZhY3Rvcl9uYW1lcyksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIiwKICAjICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDIiLCBndWlkZSA9ICJub25lIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgY2F0ZWdvcnkgJ3N1bW1hcnkgc2NvcmVzJyIsCiAgICAgICBzdWJ0aXRsZSA9ICJBZ2UgYXMgYW4gb3JkaW5hbCB2YXJpYWJsZSIsCiAgICAgICB4ID0gImFnZSAob3JkaW5hbCkiKQpgYGAKCiMjIFJlZ3Jlc3Npb25zCgpgYGB7cn0KIyBjb250cmFzdHMoZF9jYXRfc2NvcmVkJHRhcmdldF9vcmQpIDwtIGNvbnRyLnBvbHkoMTMpCiMgY29udHJhc3RzKGRfY2F0X3Njb3JlZCRmYWN0b3IpIDwtIGNvbnRyLnN1bSg0KQoKY29udHJhc3RzKGRfY2F0JHRhcmdldF9vcmQpIDwtIGNvbnRyLnBvbHkoMTMpCmNvbnRyYXN0cyhkX2NhdCRmYWN0b3IpIDwtIGNvbnRyLnN1bSg0KQpgYGAKCmBgYHtyfQpyMSA8LSBsbWVyKHJlc3BvbnNlIH4gZmFjdG9yICogcG9seSh0YXJnZXRfbnVtLCAzKSArCiAgICAgICAgICAgICAoMSArIGZhY3RvciArIHRhcmdldF9udW0gfCBzdWJpZCksCiAgICAgICAgICAgZF9jYXQgJT4lCiAgICAgICAgICAgICBtdXRhdGUodGFyZ2V0X251bSA9IHNjYWxlKHRhcmdldF9udW0sIGNlbnRlciA9IEYpKSkKCnN1bW1hcnkocjEpCmBgYAoKVGhpcyBpcyB3ZWlyZGx5IGhhcmQgdG8gbW9kZWwuLi4gbG90cyBvZiBhbHRlcm5hdGl2ZSBtb2RlbHMgZGlkbid0IGNvbnZlcmdlLiBBbHNvLCB0aG9zZSBleHRyZW1lbHkgaGlnaCB0LXZhbHVlcyBtYWtlIG1lIGEgbGl0dGxlIHN1c3BpY2lvdXMsIGFzIGRvIHRoZSBpZGVudGljYWwgc3RhbmRhcmQgZXJyb3JzIGZvciB0aGUgbGFzdCA5IHRlcm1zLiBTbywgbGV0J3MgdGFrZSB0aGlzIHdpdGggYSBiaXQgb2YgYSBncmFpbiBvZiBzYWx0IGZvciBub3cuCgoKIyBQYXJlbnRzIHZzLiBub24tcGFyZW50cwoKIyMgU3R1ZHkgMgoKIyMjIFByZWxpbWluYXJpZXMKCmBgYHtyfQpkX3BhcmVudCA8LSBkX2FsbCAlPiUKICByb3duYW1lc190b19jb2x1bW4oInN1YmlkX3RhcmdldCIpICU+JQogIG11dGF0ZShzdWJpZCA9IGdzdWIoIl8uKiQiLCAiIiwgc3ViaWRfdGFyZ2V0KSwKICAgICAgICAgdGFyZ2V0ID0gZ3N1YigiXi4qXyIsICIiLCBzdWJpZF90YXJnZXQpKSAlPiUKICBzZWxlY3QoLXN1YmlkX3RhcmdldCkgJT4lCiAgbXV0YXRlKHRhcmdldF9udW0gPSByZWNvZGUodGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMG1vIiA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDBYbW8iID0gNC8zMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDFtbyIgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMm1vIiA9IDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA0bW8iID0gNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDZtbyIgPSA2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwOW1vIiA9IDksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDEybW8iID0gMTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDE4bW8iID0gMTgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDI0bW8iID0gMjQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDM2bW8iID0gMzYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDQ4bW8iID0gNDgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDYwbW8iID0gNjApLAogICAgICAgICB0YXJnZXRfb3JkID0gcmVjb2RlX2ZhY3Rvcih0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMG1vIiA9ICJuZXdib3JucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwWG1vIiA9ICI0LWRheS1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAxbW8iID0gIjEtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMm1vIiA9ICIyLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDRtbyIgPSAiNC1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA2bW8iID0gIjYtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwOW1vIiA9ICI5LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MTJtbyIgPSAiMTItbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxOG1vIiA9ICIxOC1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDI0bW8iID0gIjIteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDM2bW8iID0gIjMteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDQ4bW8iID0gIjQteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDYwbW8iID0gIjUteWVhci1vbGRzIikpICU+JQogIGdhdGhlcihjYXBhY2l0eSwgcmVzcG9uc2UsIC1jKHN1YmlkLCBzdGFydHNfd2l0aCgidGFyZ2V0IikpKSAlPiUKICBsZWZ0X2pvaW4oZF9kZW1vICU+JQogICAgICAgICAgICAgIHNlbGVjdChSZXNwb25zZUlkLCBQYXJlbnQpICU+JQogICAgICAgICAgICAgIHJlbmFtZShzdWJpZCA9IFJlc3BvbnNlSWQsIHBhcmVudCA9IFBhcmVudCkgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHN1YmlkID0gYXMuY2hhcmFjdGVyKHN1YmlkKSkpCmBgYAoKYGBge3IsIHJlc3VsdHMgPSAiYXNpcyJ9CnBhcmVudF9jb3VudHMgPC0gZF9kZW1vICU+JSAKICBkaXN0aW5jdChSZXNwb25zZUlkLCBQYXJlbnQpICU+JSAKICByZW5hbWUoc3ViaWQgPSBSZXNwb25zZUlkLCBwYXJlbnQgPSBQYXJlbnQpICU+JQogIGNvdW50KHBhcmVudCkgJT4lIAogIG11dGF0ZShwcm9wb3J0aW9uID0gbi9zdW0obikpCgprbml0cjo6a2FibGUocGFyZW50X2NvdW50cywgZGlnaXRzID0gMykKYGBgCgpgYGB7cn0KZF9kZW1vICU+JQogIGNvdW50KFBhcmVudCwgQ2hpbGRyZW5PbGRlc3RBZ2VfY29sbGFwc2UpCmBgYAoKR2l2ZW4gdGhlc2UgbnVtYmVycywgSSB0aGluayBvdXIgYmVzdCBiZXQgaXQganVzdCB0byBsb29rIGF0IHBhcmVudHMgdnMuIG5vbi1wYXJlbnRzLCBhbmQgbm90IHRyeSB0byBzZXBhcmF0ZSBvdXQgcGFyZW50cyBvZiB5b3VuZyBjaGlsZHJlbiAodG9vIGZldyEpLgoKYGBge3J9CnNjb3Jlc19TMiA8LSBlZmFfUzIkc2NvcmVzICU+JQogIGRhdGEuZnJhbWUoKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oInN1YmlkX3RhcmdldCIpICU+JQogIG11dGF0ZShzdWJpZCA9IGdzdWIoIl8uKiQiLCAiIiwgc3ViaWRfdGFyZ2V0KSwKICAgICAgICAgdGFyZ2V0ID0gZ3N1YigiXi4qXyIsICIiLCBzdWJpZF90YXJnZXQpKSAlPiUKICBzZWxlY3QoLXN1YmlkX3RhcmdldCkgJT4lCiAgbXV0YXRlKHRhcmdldF9udW0gPSByZWNvZGUodGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMG1vIiA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDBYbW8iID0gNC8zMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDFtbyIgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMm1vIiA9IDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA0bW8iID0gNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDZtbyIgPSA2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwOW1vIiA9IDksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDEybW8iID0gMTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDE4bW8iID0gMTgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDI0bW8iID0gMjQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDM2bW8iID0gMzYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDQ4bW8iID0gNDgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDYwbW8iID0gNjApLAogICAgICAgICB0YXJnZXRfb3JkID0gcmVjb2RlX2ZhY3Rvcih0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMG1vIiA9ICJuZXdib3JucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwWG1vIiA9ICI0LWRheS1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAxbW8iID0gIjEtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMm1vIiA9ICIyLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDRtbyIgPSAiNC1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA2bW8iID0gIjYtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwOW1vIiA9ICI5LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MTJtbyIgPSAiMTItbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxOG1vIiA9ICIxOC1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDI0bW8iID0gIjIteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDM2bW8iID0gIjMteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDQ4bW8iID0gIjQteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDYwbW8iID0gIjUteWVhci1vbGRzIikpICU+JQogIGdhdGhlcihmYWN0b3IsIHNjb3JlLCAtYyhzdWJpZCwgc3RhcnRzX3dpdGgoInRhcmdldCIpKSkgJT4lCiAgbGVmdF9qb2luKGRfcGFyZW50ICU+JSBkaXN0aW5jdChzdWJpZCwgcGFyZW50KSkgJT4lCiAgbGVmdF9qb2luKGRfY2F0ICU+JSBkaXN0aW5jdChmYWN0b3IsIGZhY3Rvcl9uYW1lcykpICU+JQogIG11dGF0ZShmYWN0b3IgPSBmYWN0b3IoZmFjdG9yKSkKYGBgCgojIyMgUGxvdHMKCiMjIyMgRmFjdG9yIHNjb3JlcwoKYGBge3J9CiMgYm9vdHN0cmFwcGVkIG1lYW5zIGFuZCA5NSUgQ0lzCmRfcGFyZW50X2Jvb3QgPC0gc2NvcmVzX1MyICU+JQogIGZpbHRlcighaXMubmEocGFyZW50KSkgJT4lCiAgZ3JvdXBfYnkocGFyZW50LCB0YXJnZXQsIHRhcmdldF9udW0sIHRhcmdldF9vcmQsIGZhY3Rvcl9uYW1lcykgJT4lCiAgbXVsdGlfYm9vdF9zdGFuZGFyZCgic2NvcmUiKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZGF0YS5mcmFtZSgpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDUuNSwgZmlnLmFzcCA9IDAuNDV9CnNjb3Jlc19TMiAlPiUKICBmaWx0ZXIoIWlzLm5hKHBhcmVudCkpICU+JQogIGdncGxvdChhZXMoeCA9IHRhcmdldF9udW0sIHkgPSBzY29yZSwgY29sb3IgPSBwYXJlbnQpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjA1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX3BhcmVudF9ib290LCBhZXMoeSA9IG1lYW4sIGdyb3VwID0gcGFyZW50KSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9wYXJlbnRfYm9vdCwgZmF0dGVuID0gMS41LCAjIG5vdGU6IHRvbyBjbG9zZSB0byBkb2RnZQogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gcGFyZW50KSwgI2NvbG9yID0gImJsYWNrIiwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoLTEwLCAxMCwgMC41KSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgZmFjdG9yIHNjb3JlcywgYnkgcGFyZW50IHN0YXR1cyIsCiAgICAgICBzdWJ0aXRsZSA9ICJFeGFjdCBhZ2UsIHVudHJhbnNmb3JtZWQiLAogICAgICAgY29sb3IgPSAicGFyZW50IHN0YXR1czogIiwKICAgICAgIHggPSAidGFyZ2V0IGFnZSAobW9udGhzKSIsIHkgPSAic2NvcmUgKE5PVEU6IHNjYWxlcyBkaWZmZXIpIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNS41LCBmaWcuYXNwID0gMC40NX0Kc2NvcmVzX1MyICU+JQogIGZpbHRlcighaXMubmEocGFyZW50KSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IHBhcmVudCkpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMDUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfcGFyZW50X2Jvb3QsIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBwYXJlbnQpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4zKSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9wYXJlbnRfYm9vdCwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSwKICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuMykpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHBhcmVudCksICNjb2xvciA9ICJibGFjayIsCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlBhaXJlZCIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDYwLCAxMiksIHRyYW5zID0gInNxcnQiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTAsIDEwLCAwLjUpKSArCiAgbGFicyh0aXRsZSA9ICJEZXZlbG9wbWVudGFsIHRyYWplY3RvcmllcyBvZiBmYWN0b3Igc2NvcmVzLCBieSBwYXJlbnQgc3RhdHVzIiwKICAgICAgIHN1YnRpdGxlID0gIkV4YWN0IGFnZSwgc3F1YXJlLXJvb3QgdHJhbnNmb3JtZWQiLAogICAgICAgY29sb3IgPSAicGFyZW50IHN0YXR1czogIiwKICAgICAgIHggPSAiYWdlIGFmdGVyIHNxdWFyZS1yb290IHRyYW5zZm9ybWF0aW9uIChtb250aHMpIiwgCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDUuNSwgZmlnLmFzcCA9IDAuNDV9CnNjb3Jlc19TMiAlPiUKICBmaWx0ZXIoIWlzLm5hKHBhcmVudCkpICU+JQogIGdncGxvdChhZXMoeCA9IHRhcmdldF9vcmQsIHkgPSBzY29yZSwgY29sb3IgPSBwYXJlbnQpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjA1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX3BhcmVudF9ib290LCBhZXMoeSA9IG1lYW4sIGdyb3VwID0gcGFyZW50KSwKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSkpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfcGFyZW50X2Jvb3QsIGZhdHRlbiA9IDEuNSwKICAgICAgICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCB5bWluID0gY2lfbG93ZXIsIHltYXggPSBjaV91cHBlciksCiAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBwYXJlbnQpLCAjY29sb3IgPSAiYmxhY2siLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTAsIDEwLCAwLjUpKSArCiAgbGFicyh0aXRsZSA9ICJEZXZlbG9wbWVudGFsIHRyYWplY3RvcmllcyBvZiBmYWN0b3Igc2NvcmVzLCBieSBwYXJlbnQgc3RhdHVzIiwKICAgICAgIHN1YnRpdGxlID0gIkFnZSBhcyBvcmRpbmFsIHZhcmlhYmxlIiwKICAgICAgIGNvbG9yID0gInBhcmVudCBzdGF0dXM6ICIsCiAgICAgICB4ID0gImFnZSAob3JkaW5hbCkiLCAKICAgICAgIHkgPSAic2NvcmUgKE5PVEU6IHNjYWxlcyBkaWZmZXIpIikKYGBgCgojIyMjIENhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcycKCmBgYHtyfQojIGJvb3RzdHJhcHBlZCBtZWFucyBhbmQgOTUlIENJcwpkX2NhdF9wYXJlbnRfc2NvcmVkX2Jvb3QgPC0gZF9jYXRfc2NvcmVkICU+JQogIGZpbHRlcighaXMubmEocGFyZW50KSkgJT4lCiAgZ3JvdXBfYnkocGFyZW50LCB0YXJnZXQsIHRhcmdldF9udW0sIHRhcmdldF9vcmQsIGZhY3RvciwgZmFjdG9yX25hbWVzKSAlPiUKICBtdWx0aV9ib290X3N0YW5kYXJkKCJzY29yZSIpICU+JQogIHVuZ3JvdXAoKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LCBmaWcuYXNwID0gMC41fQpnZ3Bsb3QoZF9jYXRfcGFyZW50X3Njb3JlZF9ib290LAogICAgICAgYWVzKHggPSB0YXJnZXRfbnVtLCB5ID0gc2NvcmUsIGNvbG9yID0gcGFyZW50KSkgKwogIGZhY2V0X3dyYXAofiBmYWN0b3JfbmFtZXMsIG5jb2wgPSA0LCBzY2FsZXMgPSAiZnJlZSIpICsKICAjIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzdWJpZCksIGFscGhhID0gMC4xNSkgKwogIGdlb21fbGluZShkYXRhID0gZF9jYXRfcGFyZW50X3Njb3JlZF9ib290LCAKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCBncm91cCA9IHBhcmVudCkpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfY2F0X3BhcmVudF9zY29yZWRfYm9vdCwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZmFjdG9yX25hbWVzKSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiLAogICMgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCB1bnRyYW5zZm9ybWVkIiwKICAgICAgIHggPSAidGFyZ2V0IGFnZSAobW9udGhzKSIsCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAwLjV9CmdncGxvdChkX2NhdF9wYXJlbnRfc2NvcmVkX2Jvb3QsCiAgICAgICBhZXMoeCA9IHRhcmdldF9udW0sIHkgPSBzY29yZSwgY29sb3IgPSBwYXJlbnQpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjE1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX2NhdF9wYXJlbnRfc2NvcmVkX2Jvb3QsIAogICAgICAgICAgICBhZXMoeSA9IG1lYW4sIGdyb3VwID0gcGFyZW50KSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9jYXRfcGFyZW50X3Njb3JlZF9ib290LCBmYXR0ZW4gPSAxLjUsCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBmYWN0b3JfbmFtZXMpLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIsCiAgIyAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpLCB0cmFucyA9ICJzcXJ0IikgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiIsCiAgICAgICB4ID0gImFnZSBhZnRlciBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiAobW9udGhzKSIsCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAwLjV9CmdncGxvdChkX2NhdF9wYXJlbnRfc2NvcmVkX2Jvb3QsCiAgICAgICBhZXMoeCA9IHRhcmdldF9vcmQsIHkgPSBzY29yZSwgY29sb3IgPSBwYXJlbnQpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjE1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX2NhdF9wYXJlbnRfc2NvcmVkX2Jvb3QsIAogICAgICAgICAgICBhZXMoeSA9IG1lYW4sIGdyb3VwID0gcGFyZW50KSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9jYXRfcGFyZW50X3Njb3JlZF9ib290LCBmYXR0ZW4gPSAxLjUsCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBmYWN0b3JfbmFtZXMpLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIsCiAgIyAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxMDAsIDEwKSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgY2F0ZWdvcnkgJ3N1bW1hcnkgc2NvcmVzJyIsCiAgICAgICBzdWJ0aXRsZSA9ICJBZ2UgYXMgYW4gb3JkaW5hbCB2YXJpYWJsZSIsCiAgICAgICB4ID0gImFnZSAob3JkaW5hbCkiLAogICAgICAgeSA9ICJzY29yZSAoTk9URTogc2NhbGVzIGRpZmZlcikiKQpgYGAKCkFsbCBvZiB0aGVzZSB2aXN1YWxpemF0aW9ucyBzdWdnZXN0IHRoYXQsIHJlbGF0aXZlIHRvIG5vbi1wYXJlbnRzIChuID0gYHIgcGFyZW50X2NvdW50cyRuW3BhcmVudF9jb3VudHMkcGFyZW50ID09ICJub24tcGFyZW50Il1bMV1gKSwgcGFyZW50cyAobiA9IGByIHBhcmVudF9jb3VudHMkbltwYXJlbnRfY291bnRzJHBhcmVudCA9PSAicGFyZW50Il1bMV1gKSB0ZW5kZWQgdG8gcGVyY2VpdmUgZ3JlYXRlciBhYmlsaXRpZXMsIGluIGFsbCBkb21haW5zIGV4Y2VwdCBmb3IgYm9kaWx5IHNlbnNhdGlvbnMuIEZvciBib3RoIG5lZ2F0aXZlIGVtb3Rpb25zIGFuZCBwb3NpdGl2ZS9zb2NpYWwgZW1vdGlvbnMsIHRoaXMgZGlmZmVyZW5jZSBpcyBncmVhdGVzdCBpbiB0aGUgbWlkLXJhbmdlIG9mIHRoZSB0YXJnZXQgYWdlcyAoMTItMjQgbW9udGhzKTsgZm9yIGNvZ25pdGlvbiAmIGNvbnRyb2wsIGl0J3MgZ3JlYXRlciBhdCB0aGUgb2xkZXIgZW5kIG9mIHRoZSB0YXJnZXQgYWdlcyAoZS5nLiwgMy01IHllYXJzKS4gSXQgZG9lc24ndCBsb29rIGxpa2UgYSBodWdlIGVmZmVjdCwgYnV0IGl0J3MgaW50cnVpZ2luZy4KCiMjIyBSZWdyZXNzaW9ucwoKVGhlcmUgYXJlIG1hbnkgd2F5cyB0aGF0IHdlIGNvdWxkIGNob29zZSB0byBtb2RlbCB0aGlzIC0gSSdsbCB0cnkgb3V0IHRoZSBmYWN0b3Igc2NvcmVzIGZpcnN0LCBhZGFwdGluZyBvdXIgcHJpbWFyeSByZWdyZXNzaW9uIG1vZGVscyAobm90IGluIHRoaXMgbm90ZWJvb2spLgoKYGBge3J9CmNvbnRyYXN0cyhzY29yZXNfUzIkcGFyZW50KSA8LSBjb250ci50cmVhdG1lbnQoMiwgYmFzZSA9IDEpICMgYmFzZWxpbmU6IE5PTi1wYXJlbnRzCmNvbnRyYXN0cyhzY29yZXNfUzIkZmFjdG9yKSA8LSBjb250ci5zdW0oNCkKYGBgCgpgYGB7cn0KcjIgPC0gbG1lcihzY29yZSB+IHRhcmdldF9udW0gKiBmYWN0b3IgKiBwYXJlbnQKICAgICAgICAgICArICh0YXJnZXRfbnVtICsgZmFjdG9yIHwgc3ViaWQpLAogICAgICAgICAgIHNjb3Jlc19TMiAlPiUKICAgICAgICAgICAgIG11dGF0ZSh0YXJnZXRfbnVtID0gdGFyZ2V0X251bS8xMikpCnN1bW1hcnkocjIpCmBgYAoKVGhlIGxhc3QgdGhyZWUgY29lZmZpY2llbnRzIGhlcmUgYXJlIHdoZXJlIHRoZSBhY3Rpb24gaXM6IEFjY29yZGluZyB0byB0aGlzIG1vZGVsLCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHBhcmVudHMgYW5kIG5vbi1wYXJlbnRzIGluIHBlcmNlaXZlZCBkZXZlbG9wbWVudGFsIHRyYWplY3RvcmllcyAoYHRhcmdldF9udW06cGFyZW50MmAsIHdoaWNoIGlzIG5vdCBzaWduaWZpY2FudCBjb2xsYXBzaW5nIGFjcm9zcyBmYWN0b3JzKSBpcyBleGFnZ2VyYXRlZCBpbiB0aGUgZG9tYWluIG9mIGNvZ25pdGlvbiBhbmQgY29udHJvbCAoYHRhcmdldF9udW06ZmFjdG9yMjpwYXJlbnQyYCkgYW5kIGRpbWluaXNoZWQgaW4gdGhlIGRvbWFpbiBvZiBib2RpbHkgc2Vuc2F0aW9ucyAoYHRhcmdldF9udW06ZmFjdG9yMzpwYXJlbnQyYCkuCgpMZXQncyB0cnkgYWRkaW5nIHBvbHlub21pYWwgZWZmZWN0czoKCmBgYHtyfQpyMyA8LSBsbWVyKHNjb3JlIH4gcG9seSh0YXJnZXRfbnVtLCAzKSAqIGZhY3RvciAqIHBhcmVudAogICAgICAgICAgICsgKHBvbHkodGFyZ2V0X251bSwgMSkgKyBmYWN0b3IgfCBzdWJpZCksCiAgICAgICAgICAgc2NvcmVzX1MyICU+JQogICAgICAgICAgICAgbXV0YXRlKHRhcmdldF9udW0gPSB0YXJnZXRfbnVtLzEyKSkKc3VtbWFyeShyMykKYGBgCgpBIGxvdCB0byBzb3J0IHRocm91Z2ggaGVyZSwgYnV0IGhlcmUgYXJlIHNvbWUgb2JzZXJ2YXRpb25zOgoKLSBDb2xsYXBzaW5nIGFjcm9zcyBmYWN0b3JzLCBpdCBzZWVtcyBsaWtlIHBhcmVudHMgbWlnaHQgcGVyY2VpdmUgZXhhZ2dlcmF0ZWQgbm9uLWxpbmVhcml0aWVzPyAoYHBvbHkodGFyZ2V0X251bSwgMykyOnBhcmVudDJgIGFuZCBgcG9seSh0YXJnZXRfbnVtLCAzKTM6cGFyZW50MmApCi0gQ29tcGFyZWQgdG8gY29sbGFwc2luZyBhY3Jvc3MgZmFjdG9ycywgbm90IGEgbG90IG9mIGFkZGl0aW9uYWwgcGFyZW50IHZzLiBub24tcGFyZW50IGRpZmZlcmVuY2VzIGluIG5lZ2F0aXZlIGVtb3Rpb25zIChmYWN0b3IgMSkKLSBDb21wYXJlZCB0byBjb2xsYXBzaW5nIGFjcm9zcyBmYWN0b3JzLCBwYXJlbnRzIHBlcmNlaXZlZCBtb3JlIGRyYW1hdGljIChsaW5lYXIpIGdyb3d0aCBpbiBjb2duaXRpb24vY29udHJvbCAoZmFjdG9yIDI7IGBwb2x5KHRhcmdldF9udW0sIDMpMTpmYWN0b3IyOnBhcmVudDJgKQotIENvbXBhcmVkIHRvIGNvbGxhcHNpbmcgYWNyb3NzIGZhY3RvcnMsIGluIHRoZSBkb21haW4gb2YgYm9kaWx5IHNlbnNhdGlvbnMgKGZhY3RvciAzKSwgcGFyZW50cyBwZXJjZWl2ZWQgbGVzcyBncm93dGggKGBwb2x5KHRhcmdldF9udW0sIDMpMTpmYWN0b3IzOnBhcmVudDJgKS4gSSdtIG5vdCBzdXJlIGhvdyB0byBpbnRlcnByZXQgdGhlIGRpZmZlcmVuY2VzIGluIG5vbi1saW5lYXJpdHkgaGVyZS4KCllvdSBjb3VsZCBpbWFnaW5lIHJlLXJ1bm5pbmcgYW55IG9mIHRoZXNlIHdpdGggYSBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiBvbiB0YXJnZXQgYWdlLCBhbmQvb3Igd2l0aCB0aGUgJ3N1bW1hcnkgc2NvcmVzJyBieSBjYXRlZ29yeSwgYnV0IEknbSBub3QgZ29pbmcgdG8gZG8gdGhhdCByaWdodCBub3cuIAoKCiMjIFN0dWR5IDEKCiMjIyBQcmVsaW1pbmFyaWVzCgpgYGB7ciwgcmVzdWx0cyA9ICJhc2lzIn0KcGFyZW50X2NvdW50c19TMSA8LSBkZW1vX1MxICU+JSAKICBkaXN0aW5jdChSZXNwb25zZUlkLCBQYXJlbnQpICU+JSAKICByZW5hbWUoc3ViaWQgPSBSZXNwb25zZUlkLCBwYXJlbnQgPSBQYXJlbnQpICU+JQogIGNvdW50KHBhcmVudCkgJT4lIAogIG11dGF0ZShwcm9wb3J0aW9uID0gbi9zdW0obikpCgprbml0cjo6a2FibGUocGFyZW50X2NvdW50c19TMSwgZGlnaXRzID0gMykKYGBgCgpgYGB7cn0Kc2NvcmVzX1MxIDwtIGVmYV9TMSRzY29yZXMgJT4lCiAgZGF0YS5mcmFtZSgpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigic3ViaWRfdGFyZ2V0IikgJT4lCiAgbXV0YXRlKHN1YmlkID0gZ3N1YigiXy4qJCIsICIiLCBzdWJpZF90YXJnZXQpLAogICAgICAgICB0YXJnZXQgPSBnc3ViKCJeLipfIiwgIiIsIHN1YmlkX3RhcmdldCkpICU+JQogIHNlbGVjdCgtc3ViaWRfdGFyZ2V0KSAlPiUKICBtdXRhdGUodGFyZ2V0X251bSA9IHJlY29kZSh0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAwbW8iID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MFhtbyIgPSA0LzMwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMW1vIiA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAybW8iID0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDRtbyIgPSA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNm1vIiA9IDYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA5bW8iID0gOSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MTJtbyIgPSAxMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MThtbyIgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MjRtbyIgPSAyNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MzZtbyIgPSAzNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NDhtbyIgPSA0OCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NjBtbyIgPSA2MCksCiAgICAgICAgIHRhcmdldF9vcmQgPSByZWNvZGVfZmFjdG9yKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAwbW8iID0gIm5ld2Jvcm5zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDBYbW8iID0gIjQtZGF5LW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDFtbyIgPSAiMS1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAybW8iID0gIjItbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNG1vIiA9ICI0LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDZtbyIgPSAiNi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA5bW8iID0gIjktbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxMm1vIiA9ICIxMi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDE4bW8iID0gIjE4LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MjRtbyIgPSAiMi15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MzZtbyIgPSAiMy15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NDhtbyIgPSAiNC15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NjBtbyIgPSAiNS15ZWFyLW9sZHMiKSkgJT4lCiAgZ2F0aGVyKGZhY3Rvciwgc2NvcmUsIC1jKHN1YmlkLCBzdGFydHNfd2l0aCgidGFyZ2V0IikpKSAlPiUKICBsZWZ0X2pvaW4oZGVtb19TMSAlPiUgZGlzdGluY3QoUmVzcG9uc2VJZCwgUGFyZW50KSAlPiUKICAgICAgICAgICAgICByZW5hbWUoc3ViaWQgPSBSZXNwb25zZUlkLCBwYXJlbnQgPSBQYXJlbnQpICU+JQogICAgICAgICAgICAgIG11dGF0ZShzdWJpZCA9IGFzLmNoYXJhY3RlcihzdWJpZCkpKSAlPiUKICBtdXRhdGUoZmFjdG9yX25hbWVzID0gcmVjb2RlX2ZhY3RvcihmYWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1SNCIgPSAiTmVnYXRpdmUgZW1vdGlvbnMgKFMxIEY0KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1SMSIgPSAiQ29nbml0aW9uICYgY29udHJvbCAoUzEgRjEpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVIyIiA9ICJCb2RpbHkgc2Vuc2F0aW9ucyAoUzEgRjIpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVIzIiA9ICJQb3NpdGl2ZS9zb2NpYWwgZW1vdGlvbnMgKFMxIEYzKSIpLAogICAgICAgICBmYWN0b3IgPSBmYWN0b3IoZmFjdG9yKSkKYGBgCgojIyMgUGxvdHMKCiMjIyMgRmFjdG9yIHNjb3JlcwoKYGBge3J9CiMgYm9vdHN0cmFwcGVkIG1lYW5zIGFuZCA5NSUgQ0lzCmRfcGFyZW50X2Jvb3RfUzEgPC0gc2NvcmVzX1MxICU+JQogIGZpbHRlcighaXMubmEocGFyZW50KSkgJT4lCiAgZ3JvdXBfYnkocGFyZW50LCB0YXJnZXQsIHRhcmdldF9udW0sIHRhcmdldF9vcmQsIGZhY3Rvcl9uYW1lcykgJT4lCiAgbXVsdGlfYm9vdF9zdGFuZGFyZCgic2NvcmUiKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZGF0YS5mcmFtZSgpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDUuNSwgZmlnLmFzcCA9IDAuNDV9CnNjb3Jlc19TMSAlPiUKICBmaWx0ZXIoIWlzLm5hKHBhcmVudCkpICU+JQogIGdncGxvdChhZXMoeCA9IHRhcmdldF9udW0sIHkgPSBzY29yZSwgY29sb3IgPSBwYXJlbnQpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjA1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX3BhcmVudF9ib290X1MxLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gNSksCiAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBwYXJlbnQpKSArCiAgZ2VvbV9wb2ludHJhbmdlKGRhdGEgPSBkX3BhcmVudF9ib290X1MxLCAKICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDUpLAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gcGFyZW50KSwgI2NvbG9yID0gImJsYWNrIiwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoLTEwLCAxMCwgMC41KSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgZmFjdG9yIHNjb3JlcywgYnkgcGFyZW50IHN0YXR1cyAoU1RVRFkgMSkiLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCB1bnRyYW5zZm9ybWVkIiwKICAgICAgIGNvbG9yID0gInBhcmVudCBzdGF0dXM6ICIsCiAgICAgICB4ID0gInRhcmdldCBhZ2UgKG1vbnRocykiLCB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKSSB3b24ndCBib3RoZXIgdG8gcmUtcGxvdCB3aXRoIGRpZmZlcmVudCB0cmVhdG1lbnRzIG9mIGFnZSwgc2luY2UgdGhlcmUgYXJlIG9ubHkgdGhyZWUgdGFyZ2V0IGFnZXMgaGVyZS4KCiMjIyMgQ2F0ZWdvcnkgJ3N1bW1hcnkgc2NvcmVzJwoKYGBge3J9CiMgbWFrZSBuZXcgZGF0YWZyYW1lCmRfY2F0X1MxIDwtIGRfYWxsX1MxICU+JQogIHJlbmFtZShzdWJpZF90YXJnZXQgPSBYKSAlPiUKICBtdXRhdGUoc3ViaWQgPSBnc3ViKCJfLiokIiwgIiIsIHN1YmlkX3RhcmdldCksCiAgICAgICAgIHRhcmdldCA9IGdzdWIoIl4uKl8iLCAiIiwgc3ViaWRfdGFyZ2V0KSkgJT4lCiAgc2VsZWN0KC1zdWJpZF90YXJnZXQpICU+JQogIG11dGF0ZSh0YXJnZXRfbnVtID0gcmVjb2RlKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDBtbyIgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwWG1vIiA9IDQvMzAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAxbW8iID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDJtbyIgPSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNG1vIiA9IDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA2bW8iID0gNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDltbyIgPSA5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxMm1vIiA9IDEyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxOG1vIiA9IDE4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQyNG1vIiA9IDI0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQzNm1vIiA9IDM2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ0OG1vIiA9IDQ4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ2MG1vIiA9IDYwKSwKICAgICAgICAgdGFyZ2V0X29yZCA9IHJlY29kZV9mYWN0b3IodGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDBtbyIgPSAibmV3Ym9ybnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MFhtbyIgPSAiNC1kYXktb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMW1vIiA9ICIxLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDJtbyIgPSAiMi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA0bW8iID0gIjQtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNm1vIiA9ICI2LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDltbyIgPSAiOS1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDEybW8iID0gIjEyLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MThtbyIgPSAiMTgtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQyNG1vIiA9ICIyLXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQzNm1vIiA9ICIzLXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ0OG1vIiA9ICI0LXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ2MG1vIiA9ICI1LXllYXItb2xkcyIpKSAlPiUKICBnYXRoZXIoY2FwYWNpdHksIHJlc3BvbnNlLCAtYyhzdWJpZCwgc3RhcnRzX3dpdGgoInRhcmdldCIpKSkgJT4lCiAgbGVmdF9qb2luKGZhY3RvcnNfUzIpICU+JQogIGxlZnRfam9pbihkZW1vX1MxICU+JQogICAgICAgICAgICAgIHNlbGVjdChSZXNwb25zZUlkLCBQYXJlbnQpICU+JQogICAgICAgICAgICAgIHJlbmFtZShzdWJpZCA9IFJlc3BvbnNlSWQsIHBhcmVudCA9IFBhcmVudCkgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHN1YmlkID0gYXMuY2hhcmFjdGVyKHN1YmlkKSkpICU+JQogIGZpbHRlcighaXMubmEoZmFjdG9yKSkgIyBkcm9wIGV4dHJhIGl0ZW1zIGZyb20gUzEgbm90IGluIFMyCmBgYAoKQW5kIGdldCBhbiBhdmVyYWdlICJzY29yZSIgZm9yIGVhY2ggb2YgdGhlc2UgZmFjdG9ycyBmb3IgZWFjaCBwYXJ0aWNpcGFudDoKCmBgYHtyfQpkX2NhdF9zY29yZWRfUzEgPC0gZF9jYXRfUzEgJT4lCiAgZ3JvdXBfYnkoc3ViaWQsIHBhcmVudCwgCiAgICAgICAgICAgdGFyZ2V0LCB0YXJnZXRfbnVtLCB0YXJnZXRfb3JkLCAKICAgICAgICAgICBmYWN0b3IsIGZhY3Rvcl9uYW1lcykgJT4lCiAgc3VtbWFyaXNlKHNjb3JlID0gbWVhbihyZXNwb25zZSwgbmEucm0gPSBUKSkgJT4lCiAgdW5ncm91cCgpCmBgYAoKYGBge3J9CiMgYm9vdHN0cmFwcGVkIG1lYW5zIGFuZCA5NSUgQ0lzCmRfY2F0X3BhcmVudF9zY29yZWRfYm9vdF9TMSA8LSBkX2NhdF9zY29yZWRfUzEgJT4lCiAgZmlsdGVyKCFpcy5uYShwYXJlbnQpKSAlPiUKICBncm91cF9ieShwYXJlbnQsIHRhcmdldCwgdGFyZ2V0X251bSwgdGFyZ2V0X29yZCwgZmFjdG9yLCBmYWN0b3JfbmFtZXMpICU+JQogIG11bHRpX2Jvb3Rfc3RhbmRhcmQoInNjb3JlIikgJT4lCiAgdW5ncm91cCgpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQuNSwgZmlnLmFzcCA9IDAuNDV9CmdncGxvdChkX2NhdF9wYXJlbnRfc2NvcmVkX2Jvb3RfUzEsCiAgICAgICBhZXMoeCA9IHRhcmdldF9udW0sIHkgPSBzY29yZSwgY29sb3IgPSBwYXJlbnQpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjE1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX2NhdF9wYXJlbnRfc2NvcmVkX2Jvb3RfUzEsCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSA1KSwKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCBncm91cCA9IHBhcmVudCkpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfY2F0X3BhcmVudF9zY29yZWRfYm9vdF9TMSwKICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDUpLAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZmFjdG9yX25hbWVzKSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiLAogICMgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCB1bnRyYW5zZm9ybWVkIiwKICAgICAgIHggPSAidGFyZ2V0IGFnZSAobW9udGhzKSIsCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKTG9va2luZyBxdWlja2x5IGF0IHRoZXNlIHR3byB2aXN1YWxpemF0aW9ucyBvZiBTdHVkeSAxLCBJJ2Qgc2F5IHRoYXQgdGhlcmUncyBhIGhpbnQgb2YgdGhlIHNhbWUgcGF0dGVybnMgaW4gdGhlIGRvbWFpbnMgb2YgbmVnYXRpdmUgZW1vdGlvbnMgYW5kIHBvc2l0aXZlIHNvY2lhbCBlbW90aW9ucyAocGFyZW50cyBhdHRyaWJ1dGVkIG1vcmUgdGhhbiBub24tcGFyZW50cywgZXNwZWNpYWxseSBhdCA5IG1vbnRocyksIGFuZCBpbiBjb2duaXRpb24vY29udHJvbCAocGFyZW50cyBhdHRyaWJ1dGVkIG1vcmUgdGhhbiBub24tcGFyZW50cyBhdCA1IHllYXJzKS4gU28sIGdlbmVyYWxseSBjb25zaXN0ZW50PwoKSSB3b24ndCBydW4gcmVncmVzc2lvbiBhbmFseXNlcyBqdXN0IG5vdy4KCgojIE1lbiB2cy4gd29tZW4KCiMjIFN0dWR5IDIKCiMjIyBQcmVsaW1pbmFyaWVzCgpgYGB7cn0KZF9nZW5kZXIgPC0gZF9hbGwgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJzdWJpZF90YXJnZXQiKSAlPiUKICBtdXRhdGUoc3ViaWQgPSBnc3ViKCJfLiokIiwgIiIsIHN1YmlkX3RhcmdldCksCiAgICAgICAgIHRhcmdldCA9IGdzdWIoIl4uKl8iLCAiIiwgc3ViaWRfdGFyZ2V0KSkgJT4lCiAgc2VsZWN0KC1zdWJpZF90YXJnZXQpICU+JQogIG11dGF0ZSh0YXJnZXRfbnVtID0gcmVjb2RlKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDBtbyIgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwWG1vIiA9IDQvMzAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAxbW8iID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDJtbyIgPSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNG1vIiA9IDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA2bW8iID0gNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDltbyIgPSA5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxMm1vIiA9IDEyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxOG1vIiA9IDE4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQyNG1vIiA9IDI0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQzNm1vIiA9IDM2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ0OG1vIiA9IDQ4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ2MG1vIiA9IDYwKSwKICAgICAgICAgdGFyZ2V0X29yZCA9IHJlY29kZV9mYWN0b3IodGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDBtbyIgPSAibmV3Ym9ybnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MFhtbyIgPSAiNC1kYXktb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMW1vIiA9ICIxLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDJtbyIgPSAiMi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA0bW8iID0gIjQtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNm1vIiA9ICI2LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDltbyIgPSAiOS1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDEybW8iID0gIjEyLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MThtbyIgPSAiMTgtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQyNG1vIiA9ICIyLXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQzNm1vIiA9ICIzLXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ0OG1vIiA9ICI0LXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ2MG1vIiA9ICI1LXllYXItb2xkcyIpKSAlPiUKICBnYXRoZXIoY2FwYWNpdHksIHJlc3BvbnNlLCAtYyhzdWJpZCwgc3RhcnRzX3dpdGgoInRhcmdldCIpKSkgJT4lCiAgbGVmdF9qb2luKGRfZGVtbyAlPiUKICAgICAgICAgICAgICBzZWxlY3QoUmVzcG9uc2VJZCwgR2VuZGVyU2V4KSAlPiUKICAgICAgICAgICAgICByZW5hbWUoc3ViaWQgPSBSZXNwb25zZUlkLCBnZW5kZXIgPSBHZW5kZXJTZXgpICU+JQogICAgICAgICAgICAgIG11dGF0ZShzdWJpZCA9IGFzLmNoYXJhY3RlcihzdWJpZCkpKQpgYGAKCmBgYHtyLCByZXN1bHRzID0gImFzaXMifQpnZW5kZXJfY291bnRzIDwtIGRfZGVtbyAlPiUgCiAgZGlzdGluY3QoUmVzcG9uc2VJZCwgR2VuZGVyU2V4KSAlPiUgCiAgcmVuYW1lKHN1YmlkID0gUmVzcG9uc2VJZCwgZ2VuZGVyID0gR2VuZGVyU2V4KSAlPiUKICBjb3VudChnZW5kZXIpICU+JSAKICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKG4pKQoKa25pdHI6OmthYmxlKGdlbmRlcl9jb3VudHMsIGRpZ2l0cyA9IDMpCmBgYAoKYGBge3J9CnNjb3Jlc19TMiA8LSBlZmFfUzIkc2NvcmVzICU+JQogIGRhdGEuZnJhbWUoKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oInN1YmlkX3RhcmdldCIpICU+JQogIG11dGF0ZShzdWJpZCA9IGdzdWIoIl8uKiQiLCAiIiwgc3ViaWRfdGFyZ2V0KSwKICAgICAgICAgdGFyZ2V0ID0gZ3N1YigiXi4qXyIsICIiLCBzdWJpZF90YXJnZXQpKSAlPiUKICBzZWxlY3QoLXN1YmlkX3RhcmdldCkgJT4lCiAgbXV0YXRlKHRhcmdldF9udW0gPSByZWNvZGUodGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMG1vIiA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDBYbW8iID0gNC8zMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDFtbyIgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMm1vIiA9IDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA0bW8iID0gNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDZtbyIgPSA2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwOW1vIiA9IDksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDEybW8iID0gMTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDE4bW8iID0gMTgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDI0bW8iID0gMjQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDM2bW8iID0gMzYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDQ4bW8iID0gNDgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDYwbW8iID0gNjApLAogICAgICAgICB0YXJnZXRfb3JkID0gcmVjb2RlX2ZhY3Rvcih0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMG1vIiA9ICJuZXdib3JucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwWG1vIiA9ICI0LWRheS1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAxbW8iID0gIjEtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMm1vIiA9ICIyLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDRtbyIgPSAiNC1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA2bW8iID0gIjYtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwOW1vIiA9ICI5LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MTJtbyIgPSAiMTItbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxOG1vIiA9ICIxOC1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDI0bW8iID0gIjIteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDM2bW8iID0gIjMteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDQ4bW8iID0gIjQteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDYwbW8iID0gIjUteWVhci1vbGRzIikpICU+JQogIGdhdGhlcihmYWN0b3IsIHNjb3JlLCAtYyhzdWJpZCwgc3RhcnRzX3dpdGgoInRhcmdldCIpKSkgJT4lCiAgbGVmdF9qb2luKGRfZ2VuZGVyICU+JSBkaXN0aW5jdChzdWJpZCwgZ2VuZGVyKSkgJT4lCiAgbGVmdF9qb2luKGRfY2F0ICU+JSBkaXN0aW5jdChmYWN0b3IsIGZhY3Rvcl9uYW1lcykpICU+JQogIG11dGF0ZShmYWN0b3IgPSBmYWN0b3IoZmFjdG9yKSwgZ2VuZGVyID0gZmFjdG9yKGdlbmRlcikpCmBgYAoKIyMjIFBsb3RzCgojIyMjIEZhY3RvciBzY29yZXMKCmBgYHtyfQojIGJvb3RzdHJhcHBlZCBtZWFucyBhbmQgOTUlIENJcwpkX2dlbmRlcl9ib290IDwtIHNjb3Jlc19TMiAlPiUKICBmaWx0ZXIoIWlzLm5hKGdlbmRlcikpICU+JQogIGdyb3VwX2J5KGdlbmRlciwgdGFyZ2V0LCB0YXJnZXRfbnVtLCB0YXJnZXRfb3JkLCBmYWN0b3JfbmFtZXMpICU+JQogIG11bHRpX2Jvb3Rfc3RhbmRhcmQoInNjb3JlIikgJT4lCiAgdW5ncm91cCgpICU+JQogIGRhdGEuZnJhbWUoKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA1LjUsIGZpZy5hc3AgPSAwLjQ1fQpzY29yZXNfUzIgJT4lCiAgZmlsdGVyKCFpcy5uYShnZW5kZXIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB0YXJnZXRfbnVtLCB5ID0gc2NvcmUsIGNvbG9yID0gZ2VuZGVyKSkgKwogIGZhY2V0X3dyYXAofiBmYWN0b3JfbmFtZXMsIG5jb2wgPSA0LCBzY2FsZXMgPSAiZnJlZSIpICsKICAjIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzdWJpZCksIGFscGhhID0gMC4wNSkgKwogIGdlb21fbGluZShkYXRhID0gZF9nZW5kZXJfYm9vdCwgYWVzKHkgPSBtZWFuLCBncm91cCA9IGdlbmRlcikpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfZ2VuZGVyX2Jvb3QsIGZhdHRlbiA9IDEuNSwgIyBub3RlOiB0b28gY2xvc2UgdG8gZG9kZ2UKICAgICAgICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCB5bWluID0gY2lfbG93ZXIsIHltYXggPSBjaV91cHBlcikpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGdlbmRlciksICNjb2xvciA9ICJibGFjayIsCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTAsIDEwLCAwLjUpKSArCiAgbGFicyh0aXRsZSA9ICJEZXZlbG9wbWVudGFsIHRyYWplY3RvcmllcyBvZiBmYWN0b3Igc2NvcmVzLCBieSBwYXJ0aWNpcGFudCBnZW5kZXIiLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCB1bnRyYW5zZm9ybWVkIiwKICAgICAgIGNvbG9yID0gImdlbmRlcjogIiwKICAgICAgIHggPSAidGFyZ2V0IGFnZSAobW9udGhzKSIsIHkgPSAic2NvcmUgKE5PVEU6IHNjYWxlcyBkaWZmZXIpIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNS41LCBmaWcuYXNwID0gMC40NX0Kc2NvcmVzX1MyICU+JQogIGZpbHRlcighaXMubmEoZ2VuZGVyKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGdlbmRlcikpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMDUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfZ2VuZGVyX2Jvb3QsIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBnZW5kZXIpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4zKSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9nZW5kZXJfYm9vdCwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSwKICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuMykpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGdlbmRlciksICNjb2xvciA9ICJibGFjayIsCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpLCB0cmFucyA9ICJzcXJ0IikgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoLTEwLCAxMCwgMC41KSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgZmFjdG9yIHNjb3JlcywgYnkgcGFydGljaXBhbnQgZ2VuZGVyIiwKICAgICAgIHN1YnRpdGxlID0gIkV4YWN0IGFnZSwgc3F1YXJlLXJvb3QgdHJhbnNmb3JtZWQiLAogICAgICAgY29sb3IgPSAicGFydGljaXBhbnQgZ2VuZGVyOiAiLAogICAgICAgeCA9ICJhZ2UgYWZ0ZXIgc3F1YXJlLXJvb3QgdHJhbnNmb3JtYXRpb24gKG1vbnRocykiLCAKICAgICAgIHkgPSAic2NvcmUgKE5PVEU6IHNjYWxlcyBkaWZmZXIpIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNS41LCBmaWcuYXNwID0gMC40NX0Kc2NvcmVzX1MyICU+JQogIGZpbHRlcighaXMubmEoZ2VuZGVyKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGFyZ2V0X29yZCwgeSA9IHNjb3JlLCBjb2xvciA9IGdlbmRlcikpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMDUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfZ2VuZGVyX2Jvb3QsIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBnZW5kZXIpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9nZW5kZXJfYm9vdCwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSwKICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSkpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGdlbmRlciksICNjb2xvciA9ICJibGFjayIsCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTAsIDEwLCAwLjUpKSArCiAgbGFicyh0aXRsZSA9ICJEZXZlbG9wbWVudGFsIHRyYWplY3RvcmllcyBvZiBmYWN0b3Igc2NvcmVzLCBieSBwYXJ0aWNpcGFudCBnZW5kZXIiLAogICAgICAgc3VidGl0bGUgPSAiQWdlIGFzIG9yZGluYWwgdmFyaWFibGUiLAogICAgICAgY29sb3IgPSAicGFydGljaXBhbnQgZ2VuZGVyOiAiLAogICAgICAgeCA9ICJhZ2UgKG9yZGluYWwpIiwgCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKIyMjIyBDYXRlZ29yeSAnc3VtbWFyeSBzY29yZXMnCgpgYGB7cn0KIyBib290c3RyYXBwZWQgbWVhbnMgYW5kIDk1JSBDSXMKZF9jYXRfZ2VuZGVyX3Njb3JlZF9ib290IDwtIGRfY2F0X3Njb3JlZCAlPiUKICBsZWZ0X2pvaW4oZF9kZW1vICU+JSBkaXN0aW5jdChSZXNwb25zZUlkLCBHZW5kZXJTZXgpICU+JQogICAgICAgICAgICAgIG11dGF0ZShSZXNwb25zZUlkID0gYXMuY2hhcmFjdGVyKFJlc3BvbnNlSWQpKSAlPiUKICAgICAgICAgICAgICByZW5hbWUoc3ViaWQgPSBSZXNwb25zZUlkLCBnZW5kZXIgPSBHZW5kZXJTZXgpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGdlbmRlcikpICU+JQogIGdyb3VwX2J5KGdlbmRlciwgdGFyZ2V0LCB0YXJnZXRfbnVtLCB0YXJnZXRfb3JkLCBmYWN0b3IsIGZhY3Rvcl9uYW1lcykgJT4lCiAgbXVsdGlfYm9vdF9zdGFuZGFyZCgic2NvcmUiKSAlPiUKICB1bmdyb3VwKCkKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNCwgZmlnLmFzcCA9IDAuNX0KZ2dwbG90KGRfY2F0X2dlbmRlcl9zY29yZWRfYm9vdCwKICAgICAgIGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGdlbmRlcikpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMTUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfY2F0X2dlbmRlcl9zY29yZWRfYm9vdCwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBnZW5kZXIpKSArCiAgZ2VvbV9wb2ludHJhbmdlKGRhdGEgPSBkX2NhdF9nZW5kZXJfc2NvcmVkX2Jvb3QsIGZhdHRlbiA9IDEuNSwKICAgICAgICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCB5bWluID0gY2lfbG93ZXIsIHltYXggPSBjaV91cHBlcikpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGZhY3Rvcl9uYW1lcyksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIiwKICAjICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxMDAsIDEwKSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgY2F0ZWdvcnkgJ3N1bW1hcnkgc2NvcmVzJyIsCiAgICAgICBzdWJ0aXRsZSA9ICJFeGFjdCBhZ2UsIHVudHJhbnNmb3JtZWQiLAogICAgICAgeCA9ICJ0YXJnZXQgYWdlIChtb250aHMpIiwKICAgICAgIHkgPSAic2NvcmUgKE5PVEU6IHNjYWxlcyBkaWZmZXIpIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNCwgZmlnLmFzcCA9IDAuNX0KZ2dwbG90KGRfY2F0X2dlbmRlcl9zY29yZWRfYm9vdCwKICAgICAgIGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGdlbmRlcikpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMTUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfY2F0X2dlbmRlcl9zY29yZWRfYm9vdCwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBnZW5kZXIpKSArCiAgZ2VvbV9wb2ludHJhbmdlKGRhdGEgPSBkX2NhdF9nZW5kZXJfc2NvcmVkX2Jvb3QsIGZhdHRlbiA9IDEuNSwKICAgICAgICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCB5bWluID0gY2lfbG93ZXIsIHltYXggPSBjaV91cHBlcikpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGZhY3Rvcl9uYW1lcyksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIiwKICAjICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpLCB0cmFucyA9ICJzcXJ0IikgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiIsCiAgICAgICB4ID0gImFnZSBhZnRlciBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiAobW9udGhzKSIsCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAxLCBpbmNsdWRlID0gRn0KZ2dwbG90KGRfY2F0X2dlbmRlcl9zY29yZWRfYm9vdCwKICAgICAgIGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGdlbmRlcikpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCkgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjE1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX2NhdF9nZW5kZXJfc2NvcmVkX2Jvb3QsIAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4xKSwKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCBncm91cCA9IGdlbmRlcikpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfY2F0X2dlbmRlcl9zY29yZWRfYm9vdCwgZmF0dGVuID0gMS41LAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4xKSwKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCB5bWluID0gY2lfbG93ZXIsIHltYXggPSBjaV91cHBlcikpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGZhY3Rvcl9uYW1lcyksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIiwKICAjICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpLCB0cmFucyA9ICJzcXJ0IikgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiIsCiAgICAgICB4ID0gImFnZSBhZnRlciBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiAobW9udGhzKSIsCiAgICAgICB5ID0gInNjb3JlICgwLTEwMCkiKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LCBmaWcuYXNwID0gMC41fQpnZ3Bsb3QoZF9jYXRfZ2VuZGVyX3Njb3JlZF9ib290LAogICAgICAgYWVzKHggPSB0YXJnZXRfb3JkLCB5ID0gc2NvcmUsIGNvbG9yID0gZ2VuZGVyKSkgKwogIGZhY2V0X3dyYXAofiBmYWN0b3JfbmFtZXMsIG5jb2wgPSA0LCBzY2FsZXMgPSAiZnJlZSIpICsKICAjIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzdWJpZCksIGFscGhhID0gMC4xNSkgKwogIGdlb21fbGluZShkYXRhID0gZF9jYXRfZ2VuZGVyX3Njb3JlZF9ib290LCAKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCBncm91cCA9IGdlbmRlcikpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfY2F0X2dlbmRlcl9zY29yZWRfYm9vdCwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZmFjdG9yX25hbWVzKSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiLAogICMgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMTApKSArCiAgbGFicyh0aXRsZSA9ICJEZXZlbG9wbWVudGFsIHRyYWplY3RvcmllcyBvZiBjYXRlZ29yeSAnc3VtbWFyeSBzY29yZXMnIiwKICAgICAgIHN1YnRpdGxlID0gIkFnZSBhcyBhbiBvcmRpbmFsIHZhcmlhYmxlIiwKICAgICAgIHggPSAiYWdlIChvcmRpbmFsKSIsCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKQWxsIG9mIHRoZXNlIHZpc3VhbGl6YXRpb25zIHN1Z2dlc3QgdGhhdCwgcmVsYXRpdmUgdG8gd29tZW4sIG1lbiB0ZW5kZWQgdG8gcGVyY2VpdmUgZmV3ZXIgYWJpbGl0aWVzIGluIHRoZSBuZWdhdGl2ZSBlbW90aW9ucyBkb21haW4gKGFjcm9zcyB0aGUgYWdlIHJhbmdlKSBhbmQgaW4gdGhlIGJvZGlseSBzZW5zYXRpb25zIGRvbWFpbiAoZXNwZWNpYWxseSBmb3IgdmVyeSB5b3VuZyBpbmZhbnRzKSwgYW5kIHBlcmhhcHMgaW4gdGhlIHBvc2l0aXZlL3NvY2lhbCBlbW90aW9ucyBkb21haW4gKGZvciB0b2RkbGVycykuIEluIGNvbnRyYXN0LCBpZiBhbnl0aGlnbiBtZW4gc2VlbWVkIHRvIHBlcmNlaXZlIG1vcmUgY29nbml0aW9uICYgY29udHJvbCBhYmlsaXRpZXMgaW4gdGhlIG1pZGRsZSBhZ2UgcmFuZ2VzICh+IDEgeWVhcikuIE5vbmUgb2YgdGhlc2UgYXJlIGh1Z2UgZWZmZWN0cywgYnV0IHRoZXkgYXJlIGludHJpZ3VpbmcuCgojIyMgUmVncmVzc2lvbnMKClRoZXJlIGFyZSBtYW55IHdheXMgdGhhdCB3ZSBjb3VsZCBjaG9vc2UgdG8gbW9kZWwgdGhpcyAtIEknbGwgdHJ5IG91dCB0aGUgZmFjdG9yIHNjb3JlcyBmaXJzdCwgYWRhcHRpbmcgb3VyIHByaW1hcnkgcmVncmVzc2lvbiBtb2RlbHMgKG5vdCBpbiB0aGlzIG5vdGVib29rKS4KCmBgYHtyfQpjb250cmFzdHMoc2NvcmVzX1MyJGdlbmRlcikgPC0gY29udHIudHJlYXRtZW50KDIsIGJhc2UgPSAxKSAjIGJhc2VsaW5lOiBGRU1BTEUKY29udHJhc3RzKHNjb3Jlc19TMiRmYWN0b3IpIDwtIGNvbnRyLnN1bSg0KQpgYGAKCmBgYHtyfQpyMiA8LSBsbWVyKHNjb3JlIH4gdGFyZ2V0X251bSAqIGZhY3RvciAqIGdlbmRlcgogICAgICAgICAgICsgKHRhcmdldF9udW0gKyBmYWN0b3IgfCBzdWJpZCksCiAgICAgICAgICAgc2NvcmVzX1MyICU+JQogICAgICAgICAgICAgbXV0YXRlKHRhcmdldF9udW0gPSB0YXJnZXRfbnVtLzEyKSkKc3VtbWFyeShyMikKYGBgCgpUaGUgbGFzdCBzaXggY29lZmZpY2llbnRzIGhlcmUgYXJlIHdoZXJlIHRoZSBhY3Rpb24gaXM6IEFjY29yZGluZyB0byB0aGlzIG1vZGVsLCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG1hbGUgYW5kIGZlbWFsZSBpbiBvdmVyYWxsIG1lbnRhbCBjYXBhY2l0eSBhdHRyaWJ1dGlvbnMgKGBnZW5kZXIyYCwgd2hpY2ggaXMgbm90IHNpZ25pZmljYW50IGNvbGxhcHNpbmcgYWNyb3NzIGZhY3RvcnMgYW5kIHRhcmdldHMpIGlzIGV4YWdnZXJhdGVkIGluIHRoZSBkb21haW4gb2YgbmVnYXRpdmUgZW1vdGlvbnMgKGBmYWN0b3IxOmdlbmRlcjJgKSwgZGltaW5pc2hlZCBpbiB0aGUgZG9tYWluIG9mIGNvZ25pdGlvbiBhbmQgY29udHJvbCAoYGZhY3RvcjI6Z2VuZGVyMmApLCBhbmQgbmVpdGhlciBkaW1pbnNoZWQgbm9yIGV4YWdnZXJhdGVkIGluIHRoZSBkb21haW4gb2YgYm9kaWx5IHNlbnNhdGlvbnMgKGBmYWN0b3IzOmdlbmRlcjJgKS4gTWVhbndoaWxlLCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG1hbGUgYW5kIGZlbWFsZSBpbiBwZXJjZWl2ZWQgX2RldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzXyAoYHRhcmdldF9udW06Z2VuZGVyMmAsIHdoaWNoIGlzIG5vdCBzaWduaWZpY2FudCBjb2xsYXBzaW5nIGFjcm9zcyBmYWN0b3JzKSBpcyAobGlrZXdpc2UpIGV4YWdnZXJhdGVkIGluIHRoZSBkb21haW4gb2YgbmVnYXRpdmUgZW1vdGlvbnMgKGB0YXJnZXRfbnVtOmZhY3RvcjE6Z2VuZGVyMmApLCBkaW1pbmlzaGVkIGluIHRoZSBkb21haW4gb2YgY29nbml0aW9uIGFuZCBjb250cm9sIChgdGFyZ2V0X251bTpmYWN0b3IyOmdlbmRlcjJgKSBhbmQgZXhhZ2dlcmF0ZWQgaW4gdGhlIGRvbWFpbiBvZiBib2RpbHkgc2Vuc2F0aW9ucyAoYHRhcmdldF9udW06ZmFjdG9yMzpnZW5kZXIyYCkuCgpMZXQncyB0cnkgYWRkaW5nIHBvbHlub21pYWwgZWZmZWN0czoKCmBgYHtyfQpyMyA8LSBsbWVyKHNjb3JlIH4gcG9seSh0YXJnZXRfbnVtLCAzKSAqIGZhY3RvciAqIGdlbmRlcgogICAgICAgICAgICsgKHBvbHkodGFyZ2V0X251bSwgMSkgKyBmYWN0b3IgfCBzdWJpZCksCiAgICAgICAgICAgc2NvcmVzX1MyICU+JQogICAgICAgICAgICAgbXV0YXRlKHRhcmdldF9udW0gPSB0YXJnZXRfbnVtLzEyKSkKc3VtbWFyeShyMykKYGBgCgpBIGxvdCB0byBzb3J0IHRocm91Z2ggaGVyZSwgYnV0IGhlcmUgYXJlIHNvbWUgb2JzZXJ2YXRpb25zOgoKLSBNb3N0IG9mIHRoZSBkaWZmZXJlbmNlcyBhY3Jvc3MgZ2VuZGVycyBzZWVtIHRvIGJlIGluIHRoZSBsaW5lYXIgKG5vdCBxdWFkcmF0aWMgb3IgY3ViaWMpIGNvbXBvbmVudHMKLSBUaGUgb25lIGV4Y2VwdGlvbiB0byB0aGlzIGlzIGluIHRoZSBib2RpbHkgc2Vuc2F0aW9ucyBkb21haW4gKGZhY3RvciAzKSwgd2hlcmUgbWVuIHNlZW0gdG8gaGF2ZSBwZXJjZWl2ZWQgdGhlIHNoYXBlIG9mIHRoZSBkZXZlbG9wbWVudGFsIHRyYWplY3RvcnkgZGlmZmVyZW50bHkgYm90aCBpbiB0ZXJtcyBvZiBpdHMgcXVhZHJhdGljIChgcG9seSh0YXJnZXRfbnVtLCAyKTE6ZmFjdG9yMjpnZW5kZXIyYCkgYW5kIGl0cyBjdWJpYyAoYHBvbHkodGFyZ2V0X251bSwgMykxOmZhY3RvcjI6Z2VuZGVyMmApIGNvbXBvbmVudHMuIEJ1dCBJJ20gaGF2aW5nIGEgaGFyZCB0aW1lIGludGVycHJldGluZyB0aGUgY29lZmZpY2llbnRzIGF0IHRoaXMgcG9pbnQuCgpZb3UgY291bGQgaW1hZ2luZSByZS1ydW5uaW5nIGFueSBvZiB0aGVzZSB3aXRoIGEgc3F1YXJlLXJvb3QgdHJhbnNmb3JtYXRpb24gb24gdGFyZ2V0IGFnZSwgYW5kL29yIHdpdGggdGhlICdzdW1tYXJ5IHNjb3JlcycgYnkgY2F0ZWdvcnksIGJ1dCBJJ20gbm90IGdvaW5nIHRvIGRvIHRoYXQgcmlnaHQgbm93LiAKCgojIyBTdHVkeSAxCgojIyMgUHJlbGltaW5hcmllcwoKYGBge3IsIHJlc3VsdHMgPSAiYXNpcyJ9CmdlbmRlcl9jb3VudHNfUzEgPC0gZGVtb19TMSAlPiUgCiAgZGlzdGluY3QoUmVzcG9uc2VJZCwgR2VuZGVyU2V4KSAlPiUgCiAgcmVuYW1lKHN1YmlkID0gUmVzcG9uc2VJZCwgZ2VuZGVyID0gR2VuZGVyU2V4KSAlPiUKICBjb3VudChnZW5kZXIpICU+JSAKICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKG4pKQoKa25pdHI6OmthYmxlKGdlbmRlcl9jb3VudHNfUzEsIGRpZ2l0cyA9IDMpCmBgYAoKYGBge3J9CnNjb3Jlc19TMSA8LSBlZmFfUzEkc2NvcmVzICU+JQogIGRhdGEuZnJhbWUoKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oInN1YmlkX3RhcmdldCIpICU+JQogIG11dGF0ZShzdWJpZCA9IGdzdWIoIl8uKiQiLCAiIiwgc3ViaWRfdGFyZ2V0KSwKICAgICAgICAgdGFyZ2V0ID0gZ3N1YigiXi4qXyIsICIiLCBzdWJpZF90YXJnZXQpKSAlPiUKICBzZWxlY3QoLXN1YmlkX3RhcmdldCkgJT4lCiAgbXV0YXRlKHRhcmdldF9udW0gPSByZWNvZGUodGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMG1vIiA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDBYbW8iID0gNC8zMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDFtbyIgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMm1vIiA9IDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA0bW8iID0gNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDZtbyIgPSA2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwOW1vIiA9IDksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDEybW8iID0gMTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDE4bW8iID0gMTgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDI0bW8iID0gMjQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDM2bW8iID0gMzYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDQ4bW8iID0gNDgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDYwbW8iID0gNjApLAogICAgICAgICB0YXJnZXRfb3JkID0gcmVjb2RlX2ZhY3Rvcih0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMG1vIiA9ICJuZXdib3JucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwWG1vIiA9ICI0LWRheS1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAxbW8iID0gIjEtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMm1vIiA9ICIyLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDRtbyIgPSAiNC1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA2bW8iID0gIjYtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwOW1vIiA9ICI5LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MTJtbyIgPSAiMTItbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxOG1vIiA9ICIxOC1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDI0bW8iID0gIjIteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDM2bW8iID0gIjMteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDQ4bW8iID0gIjQteWVhci1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDYwbW8iID0gIjUteWVhci1vbGRzIikpICU+JQogIGdhdGhlcihmYWN0b3IsIHNjb3JlLCAtYyhzdWJpZCwgc3RhcnRzX3dpdGgoInRhcmdldCIpKSkgJT4lCiAgbGVmdF9qb2luKGRlbW9fUzEgJT4lIGRpc3RpbmN0KFJlc3BvbnNlSWQsIEdlbmRlclNleCkgJT4lCiAgICAgICAgICAgICAgcmVuYW1lKHN1YmlkID0gUmVzcG9uc2VJZCwgZ2VuZGVyID0gR2VuZGVyU2V4KSAlPiUKICAgICAgICAgICAgICBtdXRhdGUoc3ViaWQgPSBhcy5jaGFyYWN0ZXIoc3ViaWQpKSkgJT4lCiAgbXV0YXRlKGZhY3Rvcl9uYW1lcyA9IHJlY29kZV9mYWN0b3IoZmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNUjQiID0gIk5lZ2F0aXZlIGVtb3Rpb25zIChTMSBGNCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNUjEiID0gIkNvZ25pdGlvbiAmIGNvbnRyb2wgKFMxIEYxKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1SMiIgPSAiQm9kaWx5IHNlbnNhdGlvbnMgKFMxIEYyKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1SMyIgPSAiUG9zaXRpdmUvc29jaWFsIGVtb3Rpb25zIChTMSBGMykiKSwKICAgICAgICAgZmFjdG9yID0gZmFjdG9yKGZhY3RvcikpCmBgYAoKIyMjIFBsb3RzCgojIyMjIEZhY3RvciBzY29yZXMKCmBgYHtyfQojIGJvb3RzdHJhcHBlZCBtZWFucyBhbmQgOTUlIENJcwpkX2dlbmRlcl9ib290X1MxIDwtIHNjb3Jlc19TMSAlPiUKICBmaWx0ZXIoIWlzLm5hKGdlbmRlcikpICU+JQogIGdyb3VwX2J5KGdlbmRlciwgdGFyZ2V0LCB0YXJnZXRfbnVtLCB0YXJnZXRfb3JkLCBmYWN0b3JfbmFtZXMpICU+JQogIG11bHRpX2Jvb3Rfc3RhbmRhcmQoInNjb3JlIikgJT4lCiAgdW5ncm91cCgpICU+JQogIGRhdGEuZnJhbWUoKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA1LjUsIGZpZy5hc3AgPSAwLjQ1fQpzY29yZXNfUzEgJT4lCiAgZmlsdGVyKGdlbmRlciAlaW4lIGMoIkZlbWFsZSIsICJNYWxlIikpICU+JQogIGdncGxvdChhZXMoeCA9IHRhcmdldF9udW0sIHkgPSBzY29yZSwgY29sb3IgPSBnZW5kZXIpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjA1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX2dlbmRlcl9ib290X1MxICU+JQogICAgICAgICAgICAgIGZpbHRlcihnZW5kZXIgJWluJSBjKCJGZW1hbGUiLCAiTWFsZSIpKSwKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDUpLAogICAgICAgICAgICBhZXMoeSA9IG1lYW4sIGdyb3VwID0gZ2VuZGVyKSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9nZW5kZXJfYm9vdF9TMSAlPiUKICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoZ2VuZGVyICVpbiUgYygiRmVtYWxlIiwgIk1hbGUiKSksIAogICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gNSksCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBnZW5kZXIpLCAjY29sb3IgPSAiYmxhY2siLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoLTEwLCAxMCwgMC41KSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgZmFjdG9yIHNjb3JlcywgYnkgcGFydGljaXBhbnQgZ2VuZGVyIChTVFVEWSAxKSIsCiAgICAgICBzdWJ0aXRsZSA9ICJFeGFjdCBhZ2UsIHVudHJhbnNmb3JtZWQiLAogICAgICAgY29sb3IgPSAicGFydGljaXBhbnQgZ2VuZGVyOiAiLAogICAgICAgeCA9ICJ0YXJnZXQgYWdlIChtb250aHMpIiwgeSA9ICJzY29yZSAoTk9URTogc2NhbGVzIGRpZmZlcikiKQpgYGAKCkkgd29uJ3QgYm90aGVyIHRvIHJlLXBsb3Qgd2l0aCBkaWZmZXJlbnQgdHJlYXRtZW50cyBvZiBhZ2UsIHNpbmNlIHRoZXJlIGFyZSBvbmx5IHRocmVlIHRhcmdldCBhZ2VzIGhlcmUuCgojIyMjIENhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcycKCmBgYHtyfQojIG1ha2UgbmV3IGRhdGFmcmFtZQpkX2NhdF9TMSA8LSBkX2FsbF9TMSAlPiUKICByZW5hbWUoc3ViaWRfdGFyZ2V0ID0gWCkgJT4lCiAgbXV0YXRlKHN1YmlkID0gZ3N1YigiXy4qJCIsICIiLCBzdWJpZF90YXJnZXQpLAogICAgICAgICB0YXJnZXQgPSBnc3ViKCJeLipfIiwgIiIsIHN1YmlkX3RhcmdldCkpICU+JQogIHNlbGVjdCgtc3ViaWRfdGFyZ2V0KSAlPiUKICBtdXRhdGUodGFyZ2V0X251bSA9IHJlY29kZSh0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAwbW8iID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MFhtbyIgPSA0LzMwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMW1vIiA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAybW8iID0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDRtbyIgPSA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNm1vIiA9IDYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA5bW8iID0gOSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MTJtbyIgPSAxMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MThtbyIgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MjRtbyIgPSAyNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MzZtbyIgPSAzNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NDhtbyIgPSA0OCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NjBtbyIgPSA2MCksCiAgICAgICAgIHRhcmdldF9vcmQgPSByZWNvZGVfZmFjdG9yKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAwbW8iID0gIm5ld2Jvcm5zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDBYbW8iID0gIjQtZGF5LW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDFtbyIgPSAiMS1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAybW8iID0gIjItbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNG1vIiA9ICI0LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDZtbyIgPSAiNi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA5bW8iID0gIjktbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxMm1vIiA9ICIxMi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDE4bW8iID0gIjE4LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MjRtbyIgPSAiMi15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MzZtbyIgPSAiMy15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NDhtbyIgPSAiNC15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NjBtbyIgPSAiNS15ZWFyLW9sZHMiKSkgJT4lCiAgZ2F0aGVyKGNhcGFjaXR5LCByZXNwb25zZSwgLWMoc3ViaWQsIHN0YXJ0c193aXRoKCJ0YXJnZXQiKSkpICU+JQogIGxlZnRfam9pbihmYWN0b3JzX1MyKSAlPiUKICBsZWZ0X2pvaW4oZGVtb19TMSAlPiUKICAgICAgICAgICAgICBzZWxlY3QoUmVzcG9uc2VJZCwgR2VuZGVyU2V4KSAlPiUKICAgICAgICAgICAgICByZW5hbWUoc3ViaWQgPSBSZXNwb25zZUlkLCBnZW5kZXIgPSBHZW5kZXJTZXgpICU+JQogICAgICAgICAgICAgIG11dGF0ZShzdWJpZCA9IGFzLmNoYXJhY3RlcihzdWJpZCkpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGZhY3RvcikpICMgZHJvcCBleHRyYSBpdGVtcyBmcm9tIFMxIG5vdCBpbiBTMgpgYGAKCkFuZCBnZXQgYW4gYXZlcmFnZSAic2NvcmUiIGZvciBlYWNoIG9mIHRoZXNlIGZhY3RvcnMgZm9yIGVhY2ggcGFydGljaXBhbnQ6CgpgYGB7cn0KZF9jYXRfc2NvcmVkX1MxIDwtIGRfY2F0X1MxICU+JQogIGdyb3VwX2J5KHN1YmlkLCBnZW5kZXIsIAogICAgICAgICAgIHRhcmdldCwgdGFyZ2V0X251bSwgdGFyZ2V0X29yZCwgCiAgICAgICAgICAgZmFjdG9yLCBmYWN0b3JfbmFtZXMpICU+JQogIHN1bW1hcmlzZShzY29yZSA9IG1lYW4ocmVzcG9uc2UsIG5hLnJtID0gVCkpICU+JQogIHVuZ3JvdXAoKQpgYGAKCmBgYHtyfQojIGJvb3RzdHJhcHBlZCBtZWFucyBhbmQgOTUlIENJcwpkX2NhdF9nZW5kZXJfc2NvcmVkX2Jvb3RfUzEgPC0gZF9jYXRfc2NvcmVkX1MxICU+JQogIGZpbHRlcighaXMubmEoZ2VuZGVyKSkgJT4lCiAgZ3JvdXBfYnkoZ2VuZGVyLCB0YXJnZXQsIHRhcmdldF9udW0sIHRhcmdldF9vcmQsIGZhY3RvciwgZmFjdG9yX25hbWVzKSAlPiUKICBtdWx0aV9ib290X3N0YW5kYXJkKCJzY29yZSIpICU+JQogIHVuZ3JvdXAoKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LjUsIGZpZy5hc3AgPSAwLjQ1fQpnZ3Bsb3QoZF9jYXRfZ2VuZGVyX3Njb3JlZF9ib290X1MxICU+JQogICAgICAgICBmaWx0ZXIoZ2VuZGVyICVpbiUgYygiRmVtYWxlIiwgIk1hbGUiKSksCiAgICAgICBhZXMoeCA9IHRhcmdldF9udW0sIHkgPSBzY29yZSwgY29sb3IgPSBnZW5kZXIpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjE1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX2NhdF9nZW5kZXJfc2NvcmVkX2Jvb3RfUzEgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKGdlbmRlciAlaW4lIGMoIkZlbWFsZSIsICJNYWxlIikpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gNSksCiAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBnZW5kZXIpKSArCiAgZ2VvbV9wb2ludHJhbmdlKGRhdGEgPSBkX2NhdF9nZW5kZXJfc2NvcmVkX2Jvb3RfUzEgJT4lCiAgICAgICAgICAgICAgICAgICAgZmlsdGVyKGdlbmRlciAlaW4lIGMoIkZlbWFsZSIsICJNYWxlIikpLAogICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gNSksCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBmYWN0b3JfbmFtZXMpLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIsCiAgIyAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCB1bnRyYW5zZm9ybWVkIiwKICAgICAgIHggPSAidGFyZ2V0IGFnZSAobW9udGhzKSIsCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQuNSwgZmlnLmFzcCA9IDAuNDV9CmdncGxvdChkX2NhdF9nZW5kZXJfc2NvcmVkX2Jvb3RfUzEgJT4lCiAgICAgICAgIGZpbHRlcihnZW5kZXIgJWluJSBjKCJGZW1hbGUiLCAiTWFsZSIpKSwKICAgICAgIGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGdlbmRlcikpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMTUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfY2F0X2dlbmRlcl9zY29yZWRfYm9vdF9TMSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoZ2VuZGVyICVpbiUgYygiRmVtYWxlIiwgIk1hbGUiKSksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCBncm91cCA9IGdlbmRlcikpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfY2F0X2dlbmRlcl9zY29yZWRfYm9vdF9TMSAlPiUKICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoZ2VuZGVyICVpbiUgYygiRmVtYWxlIiwgIk1hbGUiKSksCiAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwKICAgICAgICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCB5bWluID0gY2lfbG93ZXIsIHltYXggPSBjaV91cHBlcikpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGZhY3Rvcl9uYW1lcyksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIiwKICAjICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpLCB0cmFucyA9ICJzcXJ0IikgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1lZCIsCiAgICAgICB4ID0gImFnZSBhZnRlciBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiAobW9udGhzKSIsCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQuNSwgZmlnLmFzcCA9IDAuNDV9CmdncGxvdChkX2NhdF9nZW5kZXJfc2NvcmVkX2Jvb3RfUzEgJT4lCiAgICAgICAgIGZpbHRlcihnZW5kZXIgJWluJSBjKCJGZW1hbGUiLCAiTWFsZSIpKSwKICAgICAgIGFlcyh4ID0gdGFyZ2V0X29yZCwgeSA9IHNjb3JlLCBjb2xvciA9IGdlbmRlcikpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMTUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfY2F0X2dlbmRlcl9zY29yZWRfYm9vdF9TMSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoZ2VuZGVyICVpbiUgYygiRmVtYWxlIiwgIk1hbGUiKSksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpLAogICAgICAgICAgICBhZXMoeSA9IG1lYW4sIGdyb3VwID0gZ2VuZGVyKSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9jYXRfZ2VuZGVyX3Njb3JlZF9ib290X1MxICU+JQogICAgICAgICAgICAgICAgICAgIGZpbHRlcihnZW5kZXIgJWluJSBjKCJGZW1hbGUiLCAiTWFsZSIpKSwKICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSksCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBmYWN0b3JfbmFtZXMpLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIsCiAgIyAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogICMgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxMDAsIDEwKSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgY2F0ZWdvcnkgJ3N1bW1hcnkgc2NvcmVzJyIsCiAgICAgICBzdWJ0aXRsZSA9ICJhZ2UgKG9yZGluYWwpIiwKICAgICAgIHggPSAidGFyZ2V0IiwKICAgICAgIHkgPSAic2NvcmUgKE5PVEU6IHNjYWxlcyBkaWZmZXIpIikKYGBgCgpMb29raW5nIHF1aWNrbHkgYXQgdGhlc2UgdHdvIHZpc3VhbGl6YXRpb25zIG9mIFN0dWR5IDEsIEknZCBzYXkgdGhhdCB0aGV5IGFyZSBzaW1pbGFyIHRvIHRoZSB2aXN1YWxpemF0aW9ucyBmb3IgU3R1ZHkgMiwgYm90aCBpbiB0aGUgbmVnYXRpdmUgZW1vdGlvbnMgYW5kIGJvZGlseSBkb21haW5zLiBUaGVyZSBhIGhpbnQgb2YgbW9yZSBvZiBhIGRpZmZlcmVuY2UgaGVyZSBpbiB0aGUgcG9zaXRpdmUgJiBzb2NpYWwgZW1vdGlvbnMgZG9tYWluLiBTbywgZ2VuZXJhbGx5IGNvbnNpc3RlbnQ/CgpJIHdvbid0IHJ1biByZWdyZXNzaW9uIGFuYWx5c2VzIGp1c3Qgbm93LgoKCiMgSGlnaGVyIHZzLiBsb3dlciBsZXZlbHMgb2YgZWR1Y2F0aW9uCgojIyBTdHVkeSAyCgojIyMgUHJlbGltaW5hcmllcwoKYGBge3J9CmRfZWR1IDwtIGRfYWxsICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigic3ViaWRfdGFyZ2V0IikgJT4lCiAgbXV0YXRlKHN1YmlkID0gZ3N1YigiXy4qJCIsICIiLCBzdWJpZF90YXJnZXQpLAogICAgICAgICB0YXJnZXQgPSBnc3ViKCJeLipfIiwgIiIsIHN1YmlkX3RhcmdldCkpICU+JQogIHNlbGVjdCgtc3ViaWRfdGFyZ2V0KSAlPiUKICBtdXRhdGUodGFyZ2V0X251bSA9IHJlY29kZSh0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAwbW8iID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MFhtbyIgPSA0LzMwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMW1vIiA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAybW8iID0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDRtbyIgPSA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNm1vIiA9IDYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA5bW8iID0gOSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MTJtbyIgPSAxMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MThtbyIgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MjRtbyIgPSAyNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MzZtbyIgPSAzNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NDhtbyIgPSA0OCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NjBtbyIgPSA2MCksCiAgICAgICAgIHRhcmdldF9vcmQgPSByZWNvZGVfZmFjdG9yKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAwbW8iID0gIm5ld2Jvcm5zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDBYbW8iID0gIjQtZGF5LW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDFtbyIgPSAiMS1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAybW8iID0gIjItbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNG1vIiA9ICI0LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDZtbyIgPSAiNi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA5bW8iID0gIjktbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxMm1vIiA9ICIxMi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDE4bW8iID0gIjE4LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MjRtbyIgPSAiMi15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MzZtbyIgPSAiMy15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NDhtbyIgPSAiNC15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NjBtbyIgPSAiNS15ZWFyLW9sZHMiKSkgJT4lCiAgZ2F0aGVyKGNhcGFjaXR5LCByZXNwb25zZSwgLWMoc3ViaWQsIHN0YXJ0c193aXRoKCJ0YXJnZXQiKSkpICU+JQogIGxlZnRfam9pbihkX2RlbW8gJT4lCiAgICAgICAgICAgICAgc2VsZWN0KFJlc3BvbnNlSWQsIEVkdWNhdGlvbikgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKGVkdSA9IGNhc2Vfd2hlbihhcy5udW1lcmljKEVkdWNhdGlvbikgPCA4IH4gImxlc3MgdGhhbiBhIEJBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzLm51bWVyaWMoRWR1Y2F0aW9uKSA+PSA4IH4gIkJBIG9yIG1vcmUiKSwKICAgICAgICAgICAgICAgICAgICAgZWR1ID0gZmFjdG9yKGVkdSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJsZXNzIHRoYW4gYSBCQSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCQSBvciBtb3JlIikpKSAlPiUKICAgICAgICAgICAgICByZW5hbWUoc3ViaWQgPSBSZXNwb25zZUlkKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUoc3ViaWQgPSBhcy5jaGFyYWN0ZXIoc3ViaWQpKSkKYGBgCgpgYGB7ciwgcmVzdWx0cyA9ICJhc2lzIn0KZWR1X2NvdW50cyA8LSBkX2RlbW8gJT4lIAogIGRpc3RpbmN0KFJlc3BvbnNlSWQsIEVkdWNhdGlvbikgJT4lIAogIHJlbmFtZShzdWJpZCA9IFJlc3BvbnNlSWQsIGVkdSA9IEVkdWNhdGlvbikgJT4lCiAgY291bnQoZWR1KSAlPiUgCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bShuKSkKCmtuaXRyOjprYWJsZShlZHVfY291bnRzLCBkaWdpdHMgPSAzKQpgYGAKCmBgYHtyfQpzY29yZXNfUzIgPC0gZWZhX1MyJHNjb3JlcyAlPiUKICBkYXRhLmZyYW1lKCkgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJzdWJpZF90YXJnZXQiKSAlPiUKICBtdXRhdGUoc3ViaWQgPSBnc3ViKCJfLiokIiwgIiIsIHN1YmlkX3RhcmdldCksCiAgICAgICAgIHRhcmdldCA9IGdzdWIoIl4uKl8iLCAiIiwgc3ViaWRfdGFyZ2V0KSkgJT4lCiAgc2VsZWN0KC1zdWJpZF90YXJnZXQpICU+JQogIG11dGF0ZSh0YXJnZXRfbnVtID0gcmVjb2RlKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDBtbyIgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwWG1vIiA9IDQvMzAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAxbW8iID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDJtbyIgPSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNG1vIiA9IDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA2bW8iID0gNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDltbyIgPSA5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxMm1vIiA9IDEyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxOG1vIiA9IDE4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQyNG1vIiA9IDI0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQzNm1vIiA9IDM2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ0OG1vIiA9IDQ4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ2MG1vIiA9IDYwKSwKICAgICAgICAgdGFyZ2V0X29yZCA9IHJlY29kZV9mYWN0b3IodGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDBtbyIgPSAibmV3Ym9ybnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MFhtbyIgPSAiNC1kYXktb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMW1vIiA9ICIxLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDJtbyIgPSAiMi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA0bW8iID0gIjQtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNm1vIiA9ICI2LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDltbyIgPSAiOS1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDEybW8iID0gIjEyLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MThtbyIgPSAiMTgtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQyNG1vIiA9ICIyLXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQzNm1vIiA9ICIzLXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ0OG1vIiA9ICI0LXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ2MG1vIiA9ICI1LXllYXItb2xkcyIpKSAlPiUKICBnYXRoZXIoZmFjdG9yLCBzY29yZSwgLWMoc3ViaWQsIHN0YXJ0c193aXRoKCJ0YXJnZXQiKSkpICU+JQogIGxlZnRfam9pbihkX2VkdSAlPiUgZGlzdGluY3Qoc3ViaWQsIGVkdSkpICU+JQogIGxlZnRfam9pbihkX2NhdCAlPiUgZGlzdGluY3QoZmFjdG9yLCBmYWN0b3JfbmFtZXMpKSAlPiUKICBtdXRhdGUoZmFjdG9yID0gZmFjdG9yKGZhY3RvciksIGVkdSA9IGZhY3RvcihlZHUpKQpgYGAKCiMjIyBQbG90cwoKIyMjIyBGYWN0b3Igc2NvcmVzCgpgYGB7cn0KIyBib290c3RyYXBwZWQgbWVhbnMgYW5kIDk1JSBDSXMKZF9lZHVfYm9vdCA8LSBzY29yZXNfUzIgJT4lCiAgZmlsdGVyKCFpcy5uYShlZHUpKSAlPiUKICBncm91cF9ieShlZHUsIHRhcmdldCwgdGFyZ2V0X251bSwgdGFyZ2V0X29yZCwgZmFjdG9yX25hbWVzKSAlPiUKICBtdWx0aV9ib290X3N0YW5kYXJkKCJzY29yZSIpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBkYXRhLmZyYW1lKCkKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNS41LCBmaWcuYXNwID0gMC40NX0Kc2NvcmVzX1MyICU+JQogIGZpbHRlcighaXMubmEoZWR1KSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGVkdSkpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMDUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfZWR1X2Jvb3QsIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBlZHUpKSArCiAgZ2VvbV9wb2ludHJhbmdlKGRhdGEgPSBkX2VkdV9ib290LCBmYXR0ZW4gPSAxLjUsICMgbm90ZTogdG9vIGNsb3NlIHRvIGRvZGdlCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBlZHUpLCAjY29sb3IgPSAiYmxhY2siLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTAsIDEwLCAwLjUpKSArCiAgbGFicyh0aXRsZSA9ICJEZXZlbG9wbWVudGFsIHRyYWplY3RvcmllcyBvZiBmYWN0b3Igc2NvcmVzLCBieSBwYXJ0aWNpcGFudCBlZHUiLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCB1bnRyYW5zZm9ybWVkIiwKICAgICAgIGNvbG9yID0gImVkdTogIiwKICAgICAgIHggPSAidGFyZ2V0IGFnZSAobW9udGhzKSIsIHkgPSAic2NvcmUgKE5PVEU6IHNjYWxlcyBkaWZmZXIpIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNS41LCBmaWcuYXNwID0gMC40NX0Kc2NvcmVzX1MyICU+JQogIGZpbHRlcighaXMubmEoZWR1KSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGVkdSkpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMDUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfZWR1X2Jvb3QsIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBlZHUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4zKSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9lZHVfYm9vdCwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSwKICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuMykpICsKICAjIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGVkdSksICNjb2xvciA9ICJibGFjayIsCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCBmb3JtdWxhID0gInkgfiBwb2x5KHgsIDMpIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlBhaXJlZCIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDYwLCAxMiksIHRyYW5zID0gInNxcnQiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMTAsIDEwLCAwLjUpKSArCiAgbGFicyh0aXRsZSA9ICJEZXZlbG9wbWVudGFsIHRyYWplY3RvcmllcyBvZiBmYWN0b3Igc2NvcmVzLCBieSBwYXJ0aWNpcGFudCBlZHUiLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1lZCIsCiAgICAgICBjb2xvciA9ICJwYXJ0aWNpcGFudCBlZHU6ICIsCiAgICAgICB4ID0gImFnZSBhZnRlciBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiAobW9udGhzKSIsIAogICAgICAgeSA9ICJzY29yZSAoTk9URTogc2NhbGVzIGRpZmZlcikiKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA1LjUsIGZpZy5hc3AgPSAwLjQ1fQpzY29yZXNfUzIgJT4lCiAgZmlsdGVyKCFpcy5uYShlZHUpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB0YXJnZXRfb3JkLCB5ID0gc2NvcmUsIGNvbG9yID0gZWR1KSkgKwogIGZhY2V0X3dyYXAofiBmYWN0b3JfbmFtZXMsIG5jb2wgPSA0LCBzY2FsZXMgPSAiZnJlZSIpICsKICAjIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzdWJpZCksIGFscGhhID0gMC4wNSkgKwogIGdlb21fbGluZShkYXRhID0gZF9lZHVfYm9vdCwgYWVzKHkgPSBtZWFuLCBncm91cCA9IGVkdSksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpKSArCiAgZ2VvbV9wb2ludHJhbmdlKGRhdGEgPSBkX2VkdV9ib290LCBmYXR0ZW4gPSAxLjUsCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpLAogICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZWR1KSwgI2NvbG9yID0gImJsYWNrIiwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoLTEwLCAxMCwgMC41KSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgZmFjdG9yIHNjb3JlcywgYnkgcGFydGljaXBhbnQgZWR1IiwKICAgICAgIHN1YnRpdGxlID0gIkFnZSBhcyBvcmRpbmFsIHZhcmlhYmxlIiwKICAgICAgIGNvbG9yID0gInBhcnRpY2lwYW50IGVkdTogIiwKICAgICAgIHggPSAiYWdlIChvcmRpbmFsKSIsIAogICAgICAgeSA9ICJzY29yZSAoTk9URTogc2NhbGVzIGRpZmZlcikiKQpgYGAKCiMjIyMgQ2F0ZWdvcnkgJ3N1bW1hcnkgc2NvcmVzJwoKYGBge3J9CiMgYm9vdHN0cmFwcGVkIG1lYW5zIGFuZCA5NSUgQ0lzCmRfY2F0X2VkdV9zY29yZWRfYm9vdCA8LSBkX2NhdF9zY29yZWQgJT4lCiAgbGVmdF9qb2luKGRfZGVtbyAlPiUgZGlzdGluY3QoUmVzcG9uc2VJZCwgRWR1Y2F0aW9uKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUoUmVzcG9uc2VJZCA9IGFzLmNoYXJhY3RlcihSZXNwb25zZUlkKSwKICAgICAgICAgICAgICAgICAgICAgZWR1ID0gY2FzZV93aGVuKGFzLm51bWVyaWMoRWR1Y2F0aW9uKSA8IDggfiAibGVzcyB0aGFuIGEgQkEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXMubnVtZXJpYyhFZHVjYXRpb24pID49IDggfiAiQkEgb3IgbW9yZSIpLAogICAgICAgICAgICAgICAgICAgICBlZHUgPSBmYWN0b3IoZWR1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygibGVzcyB0aGFuIGEgQkEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQkEgb3IgbW9yZSIpKSkgJT4lCiAgICAgICAgICAgICAgcmVuYW1lKHN1YmlkID0gUmVzcG9uc2VJZCkpICU+JQogIGZpbHRlcighaXMubmEoZWR1KSkgJT4lCiAgZ3JvdXBfYnkoZWR1LCB0YXJnZXQsIHRhcmdldF9udW0sIHRhcmdldF9vcmQsIGZhY3RvciwgZmFjdG9yX25hbWVzKSAlPiUKICBtdWx0aV9ib290X3N0YW5kYXJkKCJzY29yZSIpICU+JQogIHVuZ3JvdXAoKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LCBmaWcuYXNwID0gMC41fQpnZ3Bsb3QoZF9jYXRfZWR1X3Njb3JlZF9ib290LAogICAgICAgYWVzKHggPSB0YXJnZXRfbnVtLCB5ID0gc2NvcmUsIGNvbG9yID0gZWR1KSkgKwogIGZhY2V0X3dyYXAofiBmYWN0b3JfbmFtZXMsIG5jb2wgPSA0LCBzY2FsZXMgPSAiZnJlZSIpICsKICAjIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzdWJpZCksIGFscGhhID0gMC4xNSkgKwogIGdlb21fbGluZShkYXRhID0gZF9jYXRfZWR1X3Njb3JlZF9ib290LCAKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCBncm91cCA9IGVkdSkpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfY2F0X2VkdV9zY29yZWRfYm9vdCwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZmFjdG9yX25hbWVzKSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiLAogICMgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCB1bnRyYW5zZm9ybWVkIiwKICAgICAgIHggPSAidGFyZ2V0IGFnZSAobW9udGhzKSIsCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAwLjV9CmdncGxvdChkX2NhdF9lZHVfc2NvcmVkX2Jvb3QsCiAgICAgICBhZXMoeCA9IHRhcmdldF9udW0sIHkgPSBzY29yZSwgY29sb3IgPSBlZHUpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjE1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX2NhdF9lZHVfc2NvcmVkX2Jvb3QsIAogICAgICAgICAgICBhZXMoeSA9IG1lYW4sIGdyb3VwID0gZWR1KSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9jYXRfZWR1X3Njb3JlZF9ib290LCBmYXR0ZW4gPSAxLjUsCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBmYWN0b3JfbmFtZXMpLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIsCiAgIyAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpLCB0cmFucyA9ICJzcXJ0IikgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiRXhhY3QgYWdlLCBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiIsCiAgICAgICB4ID0gImFnZSBhZnRlciBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiAobW9udGhzKSIsCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDQsIGZpZy5hc3AgPSAwLjV9CmdncGxvdChkX2NhdF9lZHVfc2NvcmVkX2Jvb3QsCiAgICAgICBhZXMoeCA9IHRhcmdldF9vcmQsIHkgPSBzY29yZSwgY29sb3IgPSBlZHUpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjE1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX2NhdF9lZHVfc2NvcmVkX2Jvb3QsIAogICAgICAgICAgICBhZXMoeSA9IG1lYW4sIGdyb3VwID0gZWR1KSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9jYXRfZWR1X3Njb3JlZF9ib290LCBmYXR0ZW4gPSAxLjUsCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBmYWN0b3JfbmFtZXMpLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIsCiAgIyAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxMDAsIDEwKSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgY2F0ZWdvcnkgJ3N1bW1hcnkgc2NvcmVzJyIsCiAgICAgICBzdWJ0aXRsZSA9ICJBZ2UgYXMgYW4gb3JkaW5hbCB2YXJpYWJsZSIsCiAgICAgICB4ID0gImFnZSAob3JkaW5hbCkiLAogICAgICAgeSA9ICJzY29yZSAoTk9URTogc2NhbGVzIGRpZmZlcikiKQpgYGAKCkFsbCBvZiB0aGVzZSB2aXN1YWxpemF0aW9ucyBzdWdnZXN0IHRoYXQsIHJlbGF0aXZlIHRvIGxlc3MgZWR1Y2F0ZWQgcGFydGljaXBhbnRzLCBtb3JlIGVkdWNhdGVkIHBhcnRpY2lwYW50cyB0ZW5kZWQgdG8gcGVyY2VpdmUgc2xpZ2h0bHkgZmV3ZXIgYWJpbGl0aWVzIGluIHRoZSBuZWdhdGl2ZSBlbW90aW9ucyBkb21haW4sIGJ1dCB3ZXJlIG90aGVyd2lzZSBnZW5lcmFsbHkgdmVyeSBzaW1pbGFyLgoKIyMjIFJlZ3Jlc3Npb25zCgpUaGVyZSBhcmUgbWFueSB3YXlzIHRoYXQgd2UgY291bGQgY2hvb3NlIHRvIG1vZGVsIHRoaXMgLSBJJ2xsIHRyeSBvdXQgdGhlIGZhY3RvciBzY29yZXMgZmlyc3QsIGFkYXB0aW5nIG91ciBwcmltYXJ5IHJlZ3Jlc3Npb24gbW9kZWxzIChub3QgaW4gdGhpcyBub3RlYm9vaykuCgpgYGB7cn0KY29udHJhc3RzKHNjb3Jlc19TMiRlZHUpIDwtIGNvbnRyLnRyZWF0bWVudCgyLCBiYXNlID0gMSkgIyBiYXNlbGluZTogbGVzcyBlZHVjYXRlZApjb250cmFzdHMoc2NvcmVzX1MyJGZhY3RvcikgPC0gY29udHIuc3VtKDQpCmBgYAoKYGBge3J9CnIyIDwtIGxtZXIoc2NvcmUgfiB0YXJnZXRfbnVtICogZmFjdG9yICogZWR1CiAgICAgICAgICAgKyAodGFyZ2V0X251bSArIGZhY3RvciB8IHN1YmlkKSwKICAgICAgICAgICBzY29yZXNfUzIgJT4lCiAgICAgICAgICAgICBtdXRhdGUodGFyZ2V0X251bSA9IHRhcmdldF9udW0vMTIpKQpzdW1tYXJ5KHIyKQpgYGAKCk5hZGEuCgpMZXQncyB0cnkgYWRkaW5nIHBvbHlub21pYWwgZWZmZWN0czoKCmBgYHtyfQpyMyA8LSBsbWVyKHNjb3JlIH4gcG9seSh0YXJnZXRfbnVtLCAzKSAqIGZhY3RvciAqIGVkdQogICAgICAgICAgICsgKHBvbHkodGFyZ2V0X251bSwgMSkgKyBmYWN0b3IgfCBzdWJpZCksCiAgICAgICAgICAgc2NvcmVzX1MyICU+JQogICAgICAgICAgICAgbXV0YXRlKHRhcmdldF9udW0gPSB0YXJnZXRfbnVtLzEyKSkKc3VtbWFyeShyMykKYGBgCgpBZ2Fpbiwgbm90aGluZyBzdWJzdGFudGlhbCAtIHNvbWUgaW5kaWNhdGlvbnMgb2Ygc29tZSBlZHVjYXRpb24tcmVsYXRlZCBkaWZmZXJlbmNlcyBpbiBwZXJjZXB0aW9ucyBvZiBub24tbGluZWFyIGVmZmVjdHM/IEJ1dCBoYXJkIHRvIG1ha2UgdG9vIG11Y2ggc2Vuc2Ugb2YgdGhhdC4KCllvdSBjb3VsZCBpbWFnaW5lIHJlLXJ1bm5pbmcgYW55IG9mIHRoZXNlIHdpdGggYSBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1hdGlvbiBvbiB0YXJnZXQgYWdlLCBhbmQvb3Igd2l0aCB0aGUgJ3N1bW1hcnkgc2NvcmVzJyBieSBjYXRlZ29yeSwgYnV0IEknbSBub3QgZ29pbmcgdG8gZG8gdGhhdCByaWdodCBub3cuIAoKCiMjIFN0dWR5IDEKCiMjIyBQcmVsaW1pbmFyaWVzCgpgYGB7ciwgcmVzdWx0cyA9ICJhc2lzIn0KZWR1X2NvdW50c19TMSA8LSBkZW1vX1MxICU+JSAKICBkaXN0aW5jdChSZXNwb25zZUlkLCBFZHVjYXRpb24pICU+JSAKICBtdXRhdGUoZWR1ID0gY2FzZV93aGVuKAogICAgYXMubnVtZXJpYyhFZHVjYXRpb24pICVpbiUgYygxLCA0LCA2LCA3LCA4KSB+ICJsZXNzIHRoYW4gYSBCQSIsCiAgICBhcy5udW1lcmljKEVkdWNhdGlvbikgJWluJSBjKDIsIDMsIDUpIH4gIkJBIG9yIG1vcmUiKSwKICAgICAgICAgZWR1ID0gZmFjdG9yKGVkdSwgbGV2ZWxzID0gYygibGVzcyB0aGFuIGEgQkEiLCAiQkEgb3IgbW9yZSIpKSkgJT4lCiAgcmVuYW1lKHN1YmlkID0gUmVzcG9uc2VJZCkgJT4lCiAgY291bnQoZWR1KSAlPiUgCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bShuKSkKCmtuaXRyOjprYWJsZShlZHVfY291bnRzX1MxLCBkaWdpdHMgPSAzKQpgYGAKCmBgYHtyfQpzY29yZXNfUzEgPC0gZWZhX1MxJHNjb3JlcyAlPiUKICBkYXRhLmZyYW1lKCkgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCJzdWJpZF90YXJnZXQiKSAlPiUKICBtdXRhdGUoc3ViaWQgPSBnc3ViKCJfLiokIiwgIiIsIHN1YmlkX3RhcmdldCksCiAgICAgICAgIHRhcmdldCA9IGdzdWIoIl4uKl8iLCAiIiwgc3ViaWRfdGFyZ2V0KSkgJT4lCiAgc2VsZWN0KC1zdWJpZF90YXJnZXQpICU+JQogIG11dGF0ZSh0YXJnZXRfbnVtID0gcmVjb2RlKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDBtbyIgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwWG1vIiA9IDQvMzAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAxbW8iID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDJtbyIgPSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNG1vIiA9IDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA2bW8iID0gNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDltbyIgPSA5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxMm1vIiA9IDEyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxOG1vIiA9IDE4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQyNG1vIiA9IDI0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQzNm1vIiA9IDM2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ0OG1vIiA9IDQ4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ2MG1vIiA9IDYwKSwKICAgICAgICAgdGFyZ2V0X29yZCA9IHJlY29kZV9mYWN0b3IodGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDBtbyIgPSAibmV3Ym9ybnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MFhtbyIgPSAiNC1kYXktb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMW1vIiA9ICIxLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDJtbyIgPSAiMi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA0bW8iID0gIjQtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNm1vIiA9ICI2LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDltbyIgPSAiOS1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDEybW8iID0gIjEyLW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MThtbyIgPSAiMTgtbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQyNG1vIiA9ICIyLXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQzNm1vIiA9ICIzLXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ0OG1vIiA9ICI0LXllYXItb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQ2MG1vIiA9ICI1LXllYXItb2xkcyIpKSAlPiUKICBnYXRoZXIoZmFjdG9yLCBzY29yZSwgLWMoc3ViaWQsIHN0YXJ0c193aXRoKCJ0YXJnZXQiKSkpICU+JQogIGxlZnRfam9pbihkZW1vX1MxICU+JSBkaXN0aW5jdChSZXNwb25zZUlkLCBFZHVjYXRpb24pICU+JQogICAgICAgICAgICAgIG11dGF0ZShlZHUgPSBjYXNlX3doZW4oCiAgICAgICAgICAgICAgICBhcy5udW1lcmljKEVkdWNhdGlvbikgJWluJSBjKDEsIDQsIDYsIDcsIDgpIH4gImxlc3MgdGhhbiBhIEJBIiwKICAgICAgICAgICAgICAgIGFzLm51bWVyaWMoRWR1Y2F0aW9uKSAlaW4lIGMoMiwgMywgNSkgfiAiQkEgb3IgbW9yZSIpLAogICAgICAgICAgICAgICAgZWR1ID0gZmFjdG9yKGVkdSwgbGV2ZWxzID0gYygibGVzcyB0aGFuIGEgQkEiLCAiQkEgb3IgbW9yZSIpKSkgJT4lCiAgICAgICAgICAgICAgcmVuYW1lKHN1YmlkID0gUmVzcG9uc2VJZCkgJT4lCiAgICAgICAgICAgICAgbXV0YXRlKHN1YmlkID0gYXMuY2hhcmFjdGVyKHN1YmlkKSkpICU+JQogIG11dGF0ZShmYWN0b3JfbmFtZXMgPSByZWNvZGVfZmFjdG9yKGZhY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVI0IiA9ICJOZWdhdGl2ZSBlbW90aW9ucyAoUzEgRjQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTVIxIiA9ICJDb2duaXRpb24gJiBjb250cm9sIChTMSBGMSkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNUjIiID0gIkJvZGlseSBzZW5zYXRpb25zIChTMSBGMikiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNUjMiID0gIlBvc2l0aXZlL3NvY2lhbCBlbW90aW9ucyAoUzEgRjMpIiksCiAgICAgICAgIGZhY3RvciA9IGZhY3RvcihmYWN0b3IpKQpgYGAKCiMjIyBQbG90cwoKIyMjIyBGYWN0b3Igc2NvcmVzCgpgYGB7cn0KIyBib290c3RyYXBwZWQgbWVhbnMgYW5kIDk1JSBDSXMKZF9lZHVfYm9vdF9TMSA8LSBzY29yZXNfUzEgJT4lCiAgZmlsdGVyKCFpcy5uYShlZHUpKSAlPiUKICBncm91cF9ieShlZHUsIHRhcmdldCwgdGFyZ2V0X251bSwgdGFyZ2V0X29yZCwgZmFjdG9yX25hbWVzKSAlPiUKICBtdWx0aV9ib290X3N0YW5kYXJkKCJzY29yZSIpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBkYXRhLmZyYW1lKCkKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNS41LCBmaWcuYXNwID0gMC40NX0Kc2NvcmVzX1MxICU+JQogIGZpbHRlcighaXMubmEoZWR1KSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGVkdSkpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMDUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfZWR1X2Jvb3RfUzEgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKCFpcy5uYShlZHUpKSwKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDUpLAogICAgICAgICAgICBhZXMoeSA9IG1lYW4sIGdyb3VwID0gZWR1KSkgKwogIGdlb21fcG9pbnRyYW5nZShkYXRhID0gZF9lZHVfYm9vdF9TMSAlPiUKICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIWlzLm5hKGVkdSkpLCAKICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDUpLAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZWR1KSwgI2NvbG9yID0gImJsYWNrIiwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoLTEwLCAxMCwgMC41KSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgZmFjdG9yIHNjb3JlcywgYnkgcGFydGljaXBhbnQgZWR1Y2F0aW9uIChTVFVEWSAxKSIsCiAgICAgICBzdWJ0aXRsZSA9ICJFeGFjdCBhZ2UsIHVudHJhbnNmb3JtZWQiLAogICAgICAgY29sb3IgPSAicGFydGljaXBhbnQgZWR1OiAiLAogICAgICAgeCA9ICJ0YXJnZXQgYWdlIChtb250aHMpIiwgeSA9ICJzY29yZSAoTk9URTogc2NhbGVzIGRpZmZlcikiKQpgYGAKCkkgd29uJ3QgYm90aGVyIHRvIHJlLXBsb3Qgd2l0aCBkaWZmZXJlbnQgdHJlYXRtZW50cyBvZiBhZ2UsIHNpbmNlIHRoZXJlIGFyZSBvbmx5IHRocmVlIHRhcmdldCBhZ2VzIGhlcmUuCgojIyMjIENhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcycKCmBgYHtyfQojIG1ha2UgbmV3IGRhdGFmcmFtZQpkX2NhdF9TMSA8LSBkX2FsbF9TMSAlPiUKICByZW5hbWUoc3ViaWRfdGFyZ2V0ID0gWCkgJT4lCiAgbXV0YXRlKHN1YmlkID0gZ3N1YigiXy4qJCIsICIiLCBzdWJpZF90YXJnZXQpLAogICAgICAgICB0YXJnZXQgPSBnc3ViKCJeLipfIiwgIiIsIHN1YmlkX3RhcmdldCkpICU+JQogIHNlbGVjdCgtc3ViaWRfdGFyZ2V0KSAlPiUKICBtdXRhdGUodGFyZ2V0X251bSA9IHJlY29kZSh0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAwbW8iID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MFhtbyIgPSA0LzMwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwMW1vIiA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAybW8iID0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDRtbyIgPSA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNm1vIiA9IDYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA5bW8iID0gOSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MTJtbyIgPSAxMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MThtbyIgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MjRtbyIgPSAyNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MzZtbyIgPSAzNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NDhtbyIgPSA0OCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NjBtbyIgPSA2MCksCiAgICAgICAgIHRhcmdldF9vcmQgPSByZWNvZGVfZmFjdG9yKHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAwbW8iID0gIm5ld2Jvcm5zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDBYbW8iID0gIjQtZGF5LW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDFtbyIgPSAiMS1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDAybW8iID0gIjItbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQwNG1vIiA9ICI0LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MDZtbyIgPSAiNi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDA5bW8iID0gIjktbW9udGgtb2xkcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXQxMm1vIiA9ICIxMi1tb250aC1vbGRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldDE4bW8iID0gIjE4LW1vbnRoLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MjRtbyIgPSAiMi15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0MzZtbyIgPSAiMy15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NDhtbyIgPSAiNC15ZWFyLW9sZHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0NjBtbyIgPSAiNS15ZWFyLW9sZHMiKSkgJT4lCiAgZ2F0aGVyKGNhcGFjaXR5LCByZXNwb25zZSwgLWMoc3ViaWQsIHN0YXJ0c193aXRoKCJ0YXJnZXQiKSkpICU+JQogIGxlZnRfam9pbihmYWN0b3JzX1MyKSAlPiUKICBsZWZ0X2pvaW4oZGVtb19TMSAlPiUKICAgICAgICAgICAgICBzZWxlY3QoUmVzcG9uc2VJZCwgRWR1Y2F0aW9uKSAlPiUKICAgICAgICAgICAgICBtdXRhdGUoZWR1ID0gY2FzZV93aGVuKAogICAgICAgICAgICAgICAgYXMubnVtZXJpYyhFZHVjYXRpb24pICVpbiUgYygxLCA0LCA2LCA3LCA4KSB+ICJsZXNzIHRoYW4gYSBCQSIsCiAgICAgICAgICAgICAgICBhcy5udW1lcmljKEVkdWNhdGlvbikgJWluJSBjKDIsIDMsIDUpIH4gIkJBIG9yIG1vcmUiKSwKICAgICAgICAgICAgICAgIGVkdSA9IGZhY3RvcihlZHUsIGxldmVscyA9IGMoImxlc3MgdGhhbiBhIEJBIiwgIkJBIG9yIG1vcmUiKSkpICU+JQogICAgICAgICAgICAgIHJlbmFtZShzdWJpZCA9IFJlc3BvbnNlSWQpICU+JQogICAgICAgICAgICAgIG11dGF0ZShzdWJpZCA9IGFzLmNoYXJhY3RlcihzdWJpZCkpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGZhY3RvcikpICMgZHJvcCBleHRyYSBpdGVtcyBmcm9tIFMxIG5vdCBpbiBTMgpgYGAKCkFuZCBnZXQgYW4gYXZlcmFnZSAic2NvcmUiIGZvciBlYWNoIG9mIHRoZXNlIGZhY3RvcnMgZm9yIGVhY2ggcGFydGljaXBhbnQ6CgpgYGB7cn0KZF9jYXRfc2NvcmVkX1MxIDwtIGRfY2F0X1MxICU+JQogIGdyb3VwX2J5KHN1YmlkLCBlZHUsIAogICAgICAgICAgIHRhcmdldCwgdGFyZ2V0X251bSwgdGFyZ2V0X29yZCwgCiAgICAgICAgICAgZmFjdG9yLCBmYWN0b3JfbmFtZXMpICU+JQogIHN1bW1hcmlzZShzY29yZSA9IG1lYW4ocmVzcG9uc2UsIG5hLnJtID0gVCkpICU+JQogIHVuZ3JvdXAoKQpgYGAKCmBgYHtyfQojIGJvb3RzdHJhcHBlZCBtZWFucyBhbmQgOTUlIENJcwpkX2NhdF9lZHVfc2NvcmVkX2Jvb3RfUzEgPC0gZF9jYXRfc2NvcmVkX1MxICU+JQogIGZpbHRlcighaXMubmEoZWR1KSkgJT4lCiAgZ3JvdXBfYnkoZWR1LCB0YXJnZXQsIHRhcmdldF9udW0sIHRhcmdldF9vcmQsIGZhY3RvciwgZmFjdG9yX25hbWVzKSAlPiUKICBtdWx0aV9ib290X3N0YW5kYXJkKCJzY29yZSIpICU+JQogIHVuZ3JvdXAoKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LjUsIGZpZy5hc3AgPSAwLjQ1fQpnZ3Bsb3QoZF9jYXRfZWR1X3Njb3JlZF9ib290X1MxICU+JQogICAgICAgICBmaWx0ZXIoIWlzLm5hKGVkdSkpLAogICAgICAgYWVzKHggPSB0YXJnZXRfbnVtLCB5ID0gc2NvcmUsIGNvbG9yID0gZWR1KSkgKwogIGZhY2V0X3dyYXAofiBmYWN0b3JfbmFtZXMsIG5jb2wgPSA0LCBzY2FsZXMgPSAiZnJlZSIpICsKICAjIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzdWJpZCksIGFscGhhID0gMC4xNSkgKwogIGdlb21fbGluZShkYXRhID0gZF9jYXRfZWR1X3Njb3JlZF9ib290X1MxICU+JQogICAgICAgICAgICAgIGZpbHRlcighaXMubmEoZWR1KSksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSA1KSwKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCBncm91cCA9IGVkdSkpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfY2F0X2VkdV9zY29yZWRfYm9vdF9TMSAlPiUKICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIWlzLm5hKGVkdSkpLAogICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gNSksCiAgICAgICAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArCiAgIyBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBmYWN0b3JfbmFtZXMpLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgZm9ybXVsYSA9ICJ5IH4gcG9seSh4LCAzKSIsCiAgIyAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCB2anVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCA2MCwgMTIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxMDAsIDEwKSkgKwogIGxhYnModGl0bGUgPSAiRGV2ZWxvcG1lbnRhbCB0cmFqZWN0b3JpZXMgb2YgY2F0ZWdvcnkgJ3N1bW1hcnkgc2NvcmVzJyIsCiAgICAgICBzdWJ0aXRsZSA9ICJFeGFjdCBhZ2UsIHVudHJhbnNmb3JtZWQiLAogICAgICAgeCA9ICJ0YXJnZXQgYWdlIChtb250aHMpIiwKICAgICAgIHkgPSAic2NvcmUgKE5PVEU6IHNjYWxlcyBkaWZmZXIpIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoID0gNC41LCBmaWcuYXNwID0gMC40NX0KZ2dwbG90KGRfY2F0X2VkdV9zY29yZWRfYm9vdF9TMSAlPiUKICAgICAgICAgZmlsdGVyKCFpcy5uYShlZHUpKSwKICAgICAgIGFlcyh4ID0gdGFyZ2V0X251bSwgeSA9IHNjb3JlLCBjb2xvciA9IGVkdSkpICsKICBmYWNldF93cmFwKH4gZmFjdG9yX25hbWVzLCBuY29sID0gNCwgc2NhbGVzID0gImZyZWUiKSArCiAgIyBnZW9tX2xpbmUoYWVzKGdyb3VwID0gc3ViaWQpLCBhbHBoYSA9IDAuMTUpICsKICBnZW9tX2xpbmUoZGF0YSA9IGRfY2F0X2VkdV9zY29yZWRfYm9vdF9TMSAlPiUKICAgICAgICAgICAgICBmaWx0ZXIoIWlzLm5hKGVkdSkpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSksCiAgICAgICAgICAgIGFlcyh5ID0gbWVhbiwgZ3JvdXAgPSBlZHUpKSArCiAgZ2VvbV9wb2ludHJhbmdlKGRhdGEgPSBkX2NhdF9lZHVfc2NvcmVkX2Jvb3RfUzEgJT4lCiAgICAgICAgICAgICAgICAgICAgZmlsdGVyKCFpcy5uYShlZHUpKSwKICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpLAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZmFjdG9yX25hbWVzKSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiLAogICMgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSwgdHJhbnMgPSAic3FydCIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMTApKSArCiAgbGFicyh0aXRsZSA9ICJEZXZlbG9wbWVudGFsIHRyYWplY3RvcmllcyBvZiBjYXRlZ29yeSAnc3VtbWFyeSBzY29yZXMnIiwKICAgICAgIHN1YnRpdGxlID0gIkV4YWN0IGFnZSwgc3F1YXJlLXJvb3QgdHJhbnNmb3JtZWQiLAogICAgICAgeCA9ICJhZ2UgYWZ0ZXIgc3F1YXJlLXJvb3QgdHJhbnNmb3JtYXRpb24gKG1vbnRocykiLAogICAgICAgeSA9ICJzY29yZSAoTk9URTogc2NhbGVzIGRpZmZlcikiKQpgYGAKCmBgYHtyLCBmaWcud2lkdGggPSA0LjUsIGZpZy5hc3AgPSAwLjQ1fQpnZ3Bsb3QoZF9jYXRfZWR1X3Njb3JlZF9ib290X1MxICU+JQogICAgICAgICBmaWx0ZXIoZWR1ICVpbiUgYygiRmVtYWxlIiwgIk1hbGUiKSksCiAgICAgICBhZXMoeCA9IHRhcmdldF9vcmQsIHkgPSBzY29yZSwgY29sb3IgPSBlZHUpKSArCiAgZmFjZXRfd3JhcCh+IGZhY3Rvcl9uYW1lcywgbmNvbCA9IDQsIHNjYWxlcyA9ICJmcmVlIikgKwogICMgZ2VvbV9saW5lKGFlcyhncm91cCA9IHN1YmlkKSwgYWxwaGEgPSAwLjE1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBkX2NhdF9lZHVfc2NvcmVkX2Jvb3RfUzEgJT4lCiAgICAgICAgICAgICAgZmlsdGVyKGVkdSAlaW4lIGMoIkZlbWFsZSIsICJNYWxlIikpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSwKICAgICAgICAgICAgYWVzKHkgPSBtZWFuLCBncm91cCA9IGVkdSkpICsKICBnZW9tX3BvaW50cmFuZ2UoZGF0YSA9IGRfY2F0X2VkdV9zY29yZWRfYm9vdF9TMSAlPiUKICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoZWR1ICVpbiUgYygiRmVtYWxlIiwgIk1hbGUiKSksCiAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpLAogICAgICAgICAgICAgICAgICBhZXMoeSA9IG1lYW4sIHltaW4gPSBjaV9sb3dlciwgeW1heCA9IGNpX3VwcGVyKSkgKwogICMgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZmFjdG9yX25hbWVzKSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSAieSB+IHBvbHkoeCwgMykiLAogICMgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHZqdXN0ID0gMSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICAjIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgNjAsIDEyKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTAwLCAxMCkpICsKICBsYWJzKHRpdGxlID0gIkRldmVsb3BtZW50YWwgdHJhamVjdG9yaWVzIG9mIGNhdGVnb3J5ICdzdW1tYXJ5IHNjb3JlcyciLAogICAgICAgc3VidGl0bGUgPSAiYWdlIChvcmRpbmFsKSIsCiAgICAgICB4ID0gInRhcmdldCIsCiAgICAgICB5ID0gInNjb3JlIChOT1RFOiBzY2FsZXMgZGlmZmVyKSIpCmBgYAoKTG9va2luZyBxdWlja2x5IGF0IHRoZXNlIHR3byB2aXN1YWxpemF0aW9ucyBvZiBTdHVkeSAxLCBJJ2Qgc2F5IHRoYXQgdGhleSBhcmUgc2ltaWxhciB0byB0aGUgdmlzdWFsaXphdGlvbnMgZm9yIFN0dWR5IDIgLSBwZXJoYXBzIGEgbGl0dGxlIG1vcmUgZHJhbWF0aWMsIGVzcGVjaWFsbHkgaW4gdGhlIG5lZ2F0aXZlIGVtb3Rpb25zIGFuZCBib2RpbHkgc2Vuc2F0aW9ucyBkb21haW5zLgoKSSB3b24ndCBydW4gcmVncmVzc2lvbiBhbmFseXNlcyBqdXN0IG5vdy4KCgoKCgoK